题目描述:
Given an integer n, return the number of trailing zeroes in n!.
Note: Your solution should be in logarithmic time complexity.
要完成的函数:
int trailingZeroes(int n)
说明:
1、这道题目要求输出n!中从后面数起有多少个连续的0。时间复杂度要求是O(log)。
2、首先我们肯定不能直接计算,100!已经超过c++能处理的乘数范围了。所以我们只能仔细分析,看能不能找到一些数学规律,来统计有多少个连续的0。而且题目这种问法很明显就是要运用数学方法的。
3、经过计算,我们得到如下数据:
1! 1 0个0
2! 2 0个0
3! 6 0个0
4! 24 0个0
5! 120 1个0
6! 720 1个0
7! 5040 1个0
8! 40320 1个0
9! 362880 1个0
10! 3628800 2个0
11! 39916800 2个0
我们可以看到5!以前都是没有0的,直到24*5=120才出现了第一个0,后续再乘以6,乘以7,乘以8,乘以9都没有出现第二个0,直到乘以10再出现了第二个0。
乘以10会出现第二个0,归根结底是因为乘以了5。因为在n!中2都是充足的,只要出现了5就可以再添上一个0。
除了10=2*5之外,没有其他任何情况会生成10。
那这样子我们也可以统计出:
12! 2个0
13! 2个0
14! 2个0
15! 3个0 因为又乘以15=3*5,又添上一个0
似乎5的倍数都会添上一个0呢!
那20! 4个0 因为又乘以20=4*5,又添上一个0
25! 6个0 因为又乘以25=5*5,出现了2个5,所以又添上两个0
30! 7个0 因为又乘以30=6*5,又添上一个0
35! 8个0 因为又乘以35=7*5,又添上一个0
40! 9个0 因为又乘以40=8*5,又添上一个0
45! 10个0 因为又乘以45=9*5,又添上一个0
50! 12个0 因为又乘以50=2*5*5,又添上两个0
到这里,我们似乎可以总结出规律了,25!之所以会有6个0,是因为25/5=5,前面有5个5的间隔了(5、10、15、20、25),然后25=1*5*5,又出现一个5,所以加起来会有6个0.
50!之所以会有12个0,是因为50/5=10,前面有10个5的间隔了,然后50=2*5*5,有2个5,所以要再加上2。
75=3*5*5,所以会有18个0,75/5=15,再加上3个0,,构成18个0。
100=4*5*5,所以会有24个0,100/5=20,再加上4个0,构成24个0。
125=1*5*5*5,所以会有31个0,125/5=25,再加上5个0,再加上1个0,构成31个0。
所以对于每一个数,其实我们可以看一下,它除以5等于多少,result初始为0再加上这个数,然后这个数再除以5,看看等于多少,result再加上,然后这个数再除以5,result再加上……直到这个数最后为0。
代码如下。
代码:
int trailingZeroes(int n)
{
int result=0;
while(n)
{
n/=5;
result+=n;
}
return result;
}
非常简洁,时间复杂度也满足要求,beats 100% of cpp submissions。