최소공배수, 최대공약수 , 유클리드 호제법

대표적인 알고리즘 사이트로 백준, 프로그래머스, leetcode 등이 있으며, 초반부터 알고리즘 문제를 풀다보면 항상 마주치는 문제들이 있는데, 그 중 하나로 최소공배수, 최대공약수를 구하는 문제이다.  나의 경우는  항상 시간이 지난 후 해당 문제를 접하게 되면 기억이 나지를 않고 수학적인 부분을 고려해야 하다보니 거부감이 반복적으로 들어서 이번에 한번 차근차근 정리하고 넘어가보려고 한다.

최대공약수?

두 개 이상의 수가 공통으로 갖고 있는 수 중에서 가장 큰 수

위와같이 수를 더 이상 나누어지지 않을 때까지 나눌 시 나누는데 사용했던 모든 수를 곱하면 최대공약수가 된다.

24 : 2^3 x 3 -> 1 2 3 4  6 8 12 24 

18 : 2 x 3^2 -> 1 2 3 6 9 18

최대 공약수 : 6

최소공배수?

두 개 이상의 수가 갖는 배수 중 공통된 가장 작은  수

위와같이 수를 더 이상 나누어지지 않을 때까지 나눌 시 나누는데 사용했던 모든 수를 곱하면 최대공약수가 된다.

최소공배수 = 두 자연수의 곱 / 최대공약수로 나눈 수 임을 확인할 수 있다. 

24 -> 24 48 72 96 . . . . .

18 -> 18 36 54 72 90 .....

최소 공배수 : 72

 

서로소?

주어진 수를 반복적으로  나눌 시 더 이상 나눌 수 없는 수

위의 경우 공통되는 수로 나눌 시 최종적으로 더 이상 나눌 수 없는 수(=4  3)를 볼 수 있다.

 

유클리드 호제법 ?

2개의 자연수의 최대공약수를 구하는 알고리즘이다.
호제법 : 두 수가 서로 상대방 수를 나누어서 결국 원하는 수를 얻는 알고리즘이다.

두 수 a , b에 대하여 ( a > b) 관계가 형성될 시 a를 b로 나눈 나머지를 r이라 한다면, a와 b의 최대공약수는  b와 r의 최대공약수와 같다.

이 성질에 따라 b를 r로 나눈 나머지 r'를 구하고, 다시 r을 r'로 나눈 나머지를 구하는 과정을 반복하여 나머지가 0이 되었을 때 나누는 수가 a와 b의 최대공약수이다.

a = 24 / b = 18이라 가정 시)

  GCD a b a%b
1회 GCD(24,18) 24 18 6
2회 GCD(18,6) 18 6 0

다음과 같이 나머지 값 r을 다음에  나눌 b에  두고 기존에 b의 값을 a 값으로 하여 나눈 나머지가 0이 될 때 b에 해당하는 값이 곧 최대공약수가 된다.

 

이렇게 최대공약수를 구한다면, 최소공배수는 주어진 두 수를 곱하여 최대공약수로 나누어주면 된다.

 

public class Main {
    public static void main(String[] args) {
        int a = 24 , b = 18;
        int r = Main.gcd(a,b); //최대공약수
        int rr = (a * b) / r; //최소공배수

    }

    static int gcd(int a , int b){
        while (b > 0){
            int tmp = a;
            a = b;
            b= tmp%b;
        }
        return a;
    }
}