Coding Test/Programmers
[Lv.2] N개의 최소공배수 [프로그래머스_코딩테스트] [수학, 유클리드 호제법] [30분]
whawoo
2025. 6. 24. 15:12
반응형
🔍 문제 요약
https://school.programmers.co.kr/learn/courses/30/lessons/12953
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
1~100의 자연수의 배열 arr이 주어지고 해당 숫자들의 최소공배수를 구하는 문제.
🧠 나의 접근 방식과 시행착오
30분 정도 걸렸다. 사실 유클리드 호제법과 같은 공식적인 부분에 익숙하지 않았어서 논리적으로 생각을 해서 각 숫자들을 소인수 분해를 한 것들을 중복 체크를 해서 나온 값들을 곱하는 형태로 풀었다. 사실 이렇게 풀었어도 풀이가 길어지다 보니 확실하게 정답이 맞을지는 몰랐지만 테스트 케이스는 다 통과하긴 했던 문제.
using System;
using System.Collections.Generic;
public class Solution
{
/// <summary>
/// N개의 최소공배수
/// https://school.programmers.co.kr/learn/courses/30/lessons/12953
/// </summary>
public int solution(int[] arr)
{
// 아이템이 한개면 최소공배수는 자기 자신
if (arr.Length == 1) return arr[0];
Dictionary<int,int> yackDict = new Dictionary<int,int>();
for (int i = 0; i < arr.Length; i++)
{
int n = arr[i];
Dictionary<int,int> tempDict = new Dictionary<int,int>();
for (int j = 2; j <= n; j++)
{
if (n % j == 0)
{
if (!tempDict.ContainsKey(j))
{
tempDict.Add(j, 1);
}
else
{
tempDict[j] += 1;
}
n /= j;
j = 1;
}
}
foreach (var pair in tempDict)
{
int key = pair.Key;
int count = pair.Value;
if (!yackDict.ContainsKey(key))
{
yackDict.Add(key, count);
}
else if (yackDict[key] < count)
{
yackDict[key] = count;
}
}
}
int res = 1;
foreach (var pair in yackDict)
{
int key = pair.Key;
for (int i = 0; i < pair.Value; i++)
{
res *= key;
}
}
return res;
}
}
/// <summary>
/// C# 7.3
/// </summary>
internal class Program
{
public static void Main(string[] args)
{
var sl = new Solution();
var arr = new int[] { 2, 6, 8, 14 };
Console.Write(sl.solution(arr));
}
}
✅ 풀이 코드
피드백은 유클리드 호제법을 써서 GCD -> LCM을 해서 풀라고 한다. 코드가 확실히 간결하게 되는 장점이 있어 보이고 자주 쓰일 수 있기에 꼭 기억해두면 좋지 않을까 싶음.
public class Solution
{
public int solution(int[] arr)
{
int lcm = arr[0]; // 초기값은 첫 번째 수
for (int i = 1; i < arr.Length; i++)
{
lcm = LCM(lcm, arr[i]); // 누적해서 최소공배수 계산
}
return lcm;
}
// 최소공배수 구하는 공식: A * B / 최대공약수(GCD)
private int LCM(int a, int b)
{
return a * b / GCD(a, b);
}
// 유클리드 호제법을 이용한 최대공약수 구하기
private int GCD(int a, int b)
{
while (b != 0)
{
int temp = b;
b = a % b;
a = temp;
}
return a;
}
}
✅ 유클리드 호제법이란?
두 수 a와 b의 최대공약수는 b와 a % b의 최대공약수와 같다.
즉, GCD(a, b) = GCD(b, a % b)
이 과정을 나머지가 0이 될 때까지 반복하면 마지막 남은 값이 최대공약수다.
🧠 왜 맞는 걸까? (직관적 이해)
- a와 b가 어떤 수 d로 나눠진다면, a % b도 d로 나눠질 수밖에 없어요.
- a = b * q + r 형태로 나누었을 때, GCD(a, b)는 GCD(b, r)와 같아요.
- 이렇게 계속 나머지를 줄여가다 보면 결국 0이 되고, 가장 마지막 나눈 수가 두 수의 공통된 가장 큰 약수, 즉 최대공약수입니다.
🔄 정리
유클리드 호제법이라는게 한 번에 와닿는 느낌은 아니지만 잘 기억해두면 이곳저곳에서 쓸 수 있는 공식이긴 하다.
반응형