lintCode-2-计算出n阶乘中尾部零的个数
描述
设计一个算法,计算出n阶乘中尾部零的个数。
样例 1:
输入: 11
输出: 2
样例解释:
11! = 39916800, 结尾的0有2个。
样例 2:
输入: 5
输出: 1
样例解释:
5! = 120, 结尾的0有1个。
- 方法一:直接法
将N!先算出来,再数 零 的个数。
存在问题,不可取,阶乘数据过大,会产生溢出,而且复杂度较高。
- 方法二:数5和2的个数
为什么要数5和2的个数?
举例:5*4*3*2*1=120,首先零的个数=零的个数的10相乘。例子中5*2*4*3*1可以看出有1对5*2;同理10.*9*。。。1=5*2*9*。。*5*2*4*3*1。显然10!有两个零。
总结:找出每个阶乘因子中5的个数2的个数可以不看,因为显然2的个数永远多余5的个数。
于是
1 void count(int n) 2 { 3 int num = 0,factor = 25; //从25开始有2个5; 4 5 for (int i = 5; i <= n; i+=5) 6 { 7 num++; 8 while (i%factor == 0) 9 { 10 num++; 11 factor *= 5; 12 } 13 } 14 cout << num<<endl; 15 16 }
有问题,当数值过大时,同样会出现问题,时间开销巨大。
- 方法三,类似于方法二的方法,但是实现的角度不同。
之前方法二的算法,思路是对的,但是由于数值变大后,会造成运算复杂度的增加,比如 for()循环和"factor *=5"这是程序崩溃的主要原因。
由此,
1 void count(int n) 2 { 3 int num = 0; 4 5 n /= 5; //只要是5的倍数,则就会有0出现,N中有多少个5。则有多少个零 6 while (n != 0) 7 { 8 num += n; 9 n /= 5; //同理,5的倍数里有多少还是5的倍数的,以此种规律计算,直到结束。 10 11 } 12 cout << num << endl; 13 }
Ps:假使所有的n都不超过int表示范围,如果有需要可以另该。

浙公网安备 33010602011771号