描述
设计一个算法,计算出n阶乘中尾部零的个数
样例
11! = 39916800,因此应该返回 2
挑战
O(logN)的时间复杂度
——————————问题分割线——————————
看到题,第一思路是考虑提取因子5,有几个5就有几个0,只是这似乎是O(n)的复杂度。
还是先实现题目吧
利用for循环对5的倍数进行历遍,再通过countOf5的函数统计5因子的个数,countOf5可以通过自身的递归调用实现5因子的个数的统计。
int countOf5(long i) {
int counttemp = 0;
while (i%5 == 0)
{
counttemp = counttemp + 1;
countOf5(i / 5);
}
return counttemp;
}
long long trailingZeros(long long n) {
// write your code here, try to do it without arithmetic operators.
int count = 0;
for (size_t i = 5; i < n; i = i + 5)
{
count = count + countOf5(i);
}
return (long)count;
}
测试是通过了,但是却返回了
提示
捂脸
原来O(log n)是必须的啊
既然要log n,那必须要用更优的方法来求5的个数
想了想,才明白要这样
long count = n/5,这样就能得到5的整倍数的个数,然后再/5就能得到25整倍数的个数,以此类推,代码就变成了
long long trailingZeros(long long n) {
// write your code here, try to do it without arithmetic operators.
long count = 0;
long counttemp = n / 5;
while (counttemp != 0)
{
count = count + counttemp;
counttemp = counttemp / 5;
}
return (long)count;
}
确实在效率上优化了很多,学到了