Codewars 문제풀기 (05/22)
Number of trailing zeros of N!
-
int n을 입력으로 받는다.
-
n!에서 마지막에 붙은 0의 개수를 리턴한다.
zeros(6) 👉 6! = 720 👉 1 zeros(12) 👉 14! = 479001600 👉 2
1. Test와 리팩토링
-
테스트 1 - 입력이 0일때 0을 리턴
-
테스트 2 - 입력이 6일때 1을 리턴
-
public class Solution { public static int zeros(int n) { int fiveCount = 0; for (int i = 1; i <= n; i++) { if (i % 5 == 0) { fiveCount++; } } return fiveCount; } }
- 처음에는 1부터 n까지 다 곱해준 뒤 10으로 나누어 나머지가 0이 아닐때 까지 count를 세려고 했다. 근데 문제의 hint에 “굳이 다 곱할 필요없다”라는 말을 보고 다르게 생각을 해봤는데 n!에서 0이 붙으려면 10의 몇제곱을 곱했는가를 세면된다. 그런데 1부터 n까지 연속된 수를 곱했기 때문에 2는 어짜피 많으니까 5의 개수만 세면된다. 그래서 for문을 이용해서 5의 count를 세서 리턴해주었다.
-
테스트 3 - 입력이 25일때 6을 리턴
-
public class Solution { public static int zeros(int n) { int fiveCount = 0; while (n >= 5) { fiveCount += n / 5; n /= 5; } return fiveCount; } }
- 테스트 2의 실제 코드는 5의 거듭제곱도 5를 한번만 count한다. 그래서 반복문을 바꿨다. n을 5로 나누었을 때 몫이 5의 개수이다. 10/5=2인데, 1~10중 5, 10으로 5가 2개있다. 25는 어떨까? 25/5=5로 1~25까지 5,10,15,20에서 5가 1개씩 있고, 25에 5가 2개 있다. 그래서 반복문을 이용했다.
2. 답 비교, 느낀점
Best Practice 가장 많이 받은 코드
public class Solution {
public static int zeros(int n) {
int res = 0;
for (int i = 5; i <= n; i *= 5) {
res += n / i;
}
return res;
}
}
- n은 그대로 두고, 5의 거듭제곱으로 계속 나누어 몫들을 더했다. 같은 방법인데 조금 다른 느낌인데 연산 횟수는 이게 더 적은거 같다
신박하다고 생각한 코드
public class Solution {
public static int zeros(int n) {
if(n/5 == 0)
return 0;
return n/5 + zeros(n/5);
}
}
- 재귀로 풀었다.
- 재귀로 풀 수 있는 문제는 재귀 생각을 못하고, 재귀로 못 푸는 문제는 재귀로 풀 수 있을거같아서 삽질하고… ㅂㄷㅂㄷ
댓글남기기