【LeetCode】第172题——阶乘后的零(难度:简单)
题目描述
给定一个整数 n,返回 n! 结果尾数中零的数量。
-
示例 1:
输入: 3
输出: 0
解释: 3! = 6, 尾数中没有零。 -
示例 2:
输入: 5
输出: 1
解释: 5! = 120, 尾数中有 1 个零.
说明: 你算法的时间复杂度应为 O(log n) 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/factorial-trailing-zeroes
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
原理上是查找5与2的结对数,按理应该返回五的计数器与二的计数器的最小的那个数。但是整个遍历下来,总数上肯定前者小于后者,因此只保留五的计数器即可。
思路一:时间复杂度不为 O(log n)。每隔5个数遍历,看其可被5整除几次,计数器便加几,最终返回计数器的个数。
思路二:时间复杂度为 O(log n)。
本人尽量描述详细,便于读者理解。(注意此思路二部分的“/”均为java下的整除符号,“=”为数学意义下的等号,而非java意义下的赋值)
-
对输入n进行处理:n/5=a1可以表示为有多少个数能被5整除,而能被5整除意味着这些数至少都能被5整除1次,即计数器加1×a1。
-
继续,还是对n进行处理:n/25=a2可以表示为有多少个数能被25整除,而能被25整除意味着这些数至少都能被5整除2次,除去n/5的那1次,还有1次,即计数器再加1×a2。
-
再继续,还是对n进行处理:n/125=a3可以表示为有多少个数能被125整除,而能被125整除意味着这些数至少都能被5整除3次,除去n/25的那2次,还有1次,即计数器再加1×a3。
-
继续推…
会发现五的计数器最后的计数值表示为"a1+a2+a3+…",表示为:n 5 + n 25 + n 125 + . . . \frac{n}{5}+\frac{n}{25}+\frac{n}{125}+... 5n+25n+125n+...(除法为整除)
又可表示为:
n 5 + n 5 5 + n 5 5 5 + . . . \frac{n}{5}+\frac{\frac{n}{5}}{5}+\frac{\frac{\frac{n}{5}}{5}}{5}+... 5n+55n+555n+...(除法为整除)
即不断进行n/5的操作,并把整除后得到的数累加。
应该是讲明白思路了吧。
代码详解
思路一:每隔5个数遍历
class Solution {
public int trailingZeroes(int n) {
int count_five = 0; // 计数器
for(int i = 5; i <= n; i = i + 5) { // 每隔5个遍历
int num = i;
while(true) {
if(num % 5 == 0){ // 看能被5整除几次
++count_five;
num = num / 5;
} else {
break;
}
}
}
return count_five;
}
}
思路二:不断整除5(推荐)
如果看不懂代码或原理,还是麻烦返回上面查看思路二的解释,已经解释得很详细啦!
class Solution {
public int trailingZeroes(int n) {
int count_five = 0;
while(n > 0) {
n = n / 5; // 不断整除5
count_five = count_five + n; // 结果累加
}
return count_five;
}
}
注意点
- 如果题目看起来和数学计算相关,可以思考一下能否用数学的方式来解决问题。