Given an integer n, return the number of trailing zeroes in n!.
Note: Your solution should be in logarithmic time complexity.
难度系数:容易
题目大意:给定一个整数n,返回n!的末尾0的个数,要求对数阶时间复杂度。
乍一看,这确实不难,很简单的做法是先求n!嘛,然后求0的个数。结果是没问题,但是时间复杂度不符合要求,求n!就要O(n)的时间复杂度。
虽然说那样做不符合要求,但你稍微思考下,也轻松发现有更好的办法。0的个数跟有多少个10相乘有关,而要产生10,分解下就得有2和5,很容易发现,阶乘过程中,能分解成5的数一定比能分解成2的数要少。因此,就看n!能有多少个数可以分解成5的。
我当时就是这么想的,5!有1个5,10!有2个5,于是我就得出:
int trailingZeroes(int n) {
return n / 5;
}
然后我就傻傻地提交了,结果当然就做错了。并且告诉我输入30,应该是7,而我的结果是6。
我就思考,为什么会多出个0呢,原来25 * 4 就可以得到2个0。即25可以分解为两个5,因此,当n/5 >= 5时,还应该继续除下去。于是改成这样:
int trailingZeroes(int n) {
if (n / 5 < 5) {
return n / 5;
} else {
return n /5 + trailingZeroes(n / 5);
}
}
我再次提交,这回就正确了。
好吧,我老实地写出来,我是有压力的。因为这题并不难,我却第一次做错了。只要写完简单地验证下,也可以发现错误。事实上,我是有验证的,我写了个求阶乘的函数,参数类型是long,蛋疼的是,到25!的时候,溢出了。这就让我看不到结果有几个0,我当时认为前面几个数验证都对了,应该没问题了吧,我想。就这样,第一次提交出错了。
这题就讲解到这里了。以前没刷过算法题,之所以现在开始刷,是因为我感觉自己练的不够多,编码能力不强,顺便掌握写常用的算法。当我不知道自己做什么的时候,我就去刷题,并把每一道题都记录成blog,代码全部用C++来写。