아니 진짜 이 문제는 볼 때마다 항상 헷갈린다... 분자 분모 더할 때 뭔가 느낌은 알겠는데, 매번 코드로 옮길 때 막혀서 짜증남 ㅋㅋ
이번 기회에 좀 확실히 정리해놔야겠다.
문제는 간단하다. 두 분수를 더해서 기약 분수로 만들어야 함. (분모 같게 만든 다음 분자끼리 더하고, 마지막에 최대공약수로 약분)
일단 내 첫 풀이:
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문 돌리는 방식은 나중에 복잡한 문제 나오면 시간 초과 뜰 수 있으니까, 처음부터 습관을 유클리드 방식으로 들여놔야 할 듯.
아무튼 이번엔 두 방식 다 한번 써봤으니까, 다음에 또 나오면 바로 유클리드 써야지. 까먹지 말자 제발...
댓글
댓글 작성은 로그인 후에 가능합니다.