尾部的零的问题

问题描述:

设计一个算法,计算出n阶乘中尾部零的个数

样例

11! = 39916800,因此应该返回 2

挑战

O(logN)的时间复杂度

解决方法:
常规思路第一步想到的是计算出n!,然而这种方法不仅计算量大,计算时间长,时间复杂度大于O(logN)。并且,更严重的问题是:会产生溢出
我们知道 long long 型的数表示的最大值是2^63-1,而阶乘很容易超过这个数,所以会产生溢出。
注意:
1、C语言中^不表示幂次方,而是位异或,幂次方正确应该是调用pow函数。
2、注意符号数和无符号数的区别。

正确方法:
分解质因素,尾数为零的情况是:尾数为5和尾数为偶数的数相乘。比如:11!=1x2x3x4x5x6x7x8x9x10x11。乘法中只要有5的倍数就会使得到的积尾数就增加一个零,因此只要算出乘数中5的个数。但是,进一步发现,乘数为25的倍数的数,与偶数(比如4)相乘得到的积尾数会增加两个0。以此类推,乘数为125的倍数的数,与偶数(比如8)相乘得到的积尾数会增加三个0 ……
由于是阶乘,所以肯定有足够的偶数满足要求。

这样,算法的思想是:循环除5,将依次得到的商加起来。代码如下:

class Solution {
public:
    /*
     * @param n: A long integer
     * @return: An integer, denote the number of trailing zeros in n!
     */
    long long trailingZeros(long long n) {
        // write your code here, try to do it without arithmetic operators.


        long long count=0;
        while(n!=0){
            n=n/5;
            count+=n;
        }
        return count;

    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值