아니 진짜 이 문제는 볼 때마다 항상 헷갈린다... 분자 분모 더할 때 뭔가 느낌은 알겠는데, 매번 코드로 옮길 때 막혀서 짜증남 ㅋㅋ 이번 기회에 좀 확실히 정리해놔야겠다. 문제는 간단하다. 두 분수를 더해서 기약 분수로 만들어야 함. (분모 같게 만든 다음 분자끼리 더하고, 마지막에 최대공약수로 약분) 일단 내 첫 풀이:

class Solution {
    public int[] solution(int numer1, int denom1, int numer2, int denom2) {
        int[] answer = new int[2]; 
        int numerSum = numer1*denom2 + numer2*denom1;  // 분자의 합
        int denomSum = denom1 * denom2;  // 분모의 합
        int max = 1;
        
        for(int i = 1; i < =numerSum; i++){
            if(numerSum%i == 0 && denomSum%i == 0){
                max = i;
            }
        }
        answer[0] = numerSum/max;
        answer[1] = denomSum/max;
        return answer;
    }
}

분모를 그냥 서로 곱해서 통일시키는 건 나쁘지 않은데, 사실 최소공배수로 맞추는 게 더 좋은 방법이긴 하다. 근데 이 문제는 그냥 denom1 * denom2로 해도 통과되긴 함. 최대공약수 구하는 거를 for문 돌려서 찾았는데, 솔직히 유클리드 호제법 쓰는 게 훨씬 빠르고 깔끔함. (시간 복잡도 생각하면 for문은 너무 비효율적임...) 그래서 이번 기회에 유클리드 호제법으로 짠 다른 풀이도 추가해봤다.

class Solution { 
     public int[] solution(int numer1, int denom1, int numer2, int denom2) { 
          int numerSum = numer1 * denom2 + numer2 * denom1; 
          int denomSum = denom1 * denom2; 
          int gcd = getGCD(numerSum, denomSum); 
 
          return new int[]{numerSum / gcd, denomSum / gcd}; 
      } 

      private int getGCD(int a, int b) { 
           while(b != 0) { 
                 int temp = a % b; a = b; b = temp; 
           } 
           return a; 
      } 
}

gcd 구하는 로직은 암기해야 한다. 면접 때 물어보는 경우도 은근히 있음. for문 돌리는 방식은 나중에 복잡한 문제 나오면 시간 초과 뜰 수 있으니까, 처음부터 습관을 유클리드 방식으로 들여놔야 할 듯. 아무튼 이번엔 두 방식 다 한번 써봤으니까, 다음에 또 나오면 바로 유클리드 써야지. 까먹지 말자 제발...