计算n阶乘的末尾有几个0

一、问题描述:在lintcode上有这么一个问题,如下图所示。设计一个算法,计算出n阶乘中尾部零的个数。

二、尝试

(1)相信很多人看到这个问题的第一个想法就是,先计算n阶乘的结果,然后对10进行求余判断,而被10整除的次数就是尾部零的个数。代码如下:

long long trailingZeros(long long n) {
        // write your code here, try to do it without arithmetic operators.
        //计算n阶乘
        int s=1;
        for(int i=1;i<=n;i++)
        {
            s=s*i;
        }
        //对结果进行判断
        int num = 0;
        //对10进行求余
        while(s%10==0)
        {
            num++;
            s = s/10;
        }
        return num;
    }

看结果,说容易陷入死循环。为什么会陷入死循环呢?n才是105哎,105!等于多少?用了一个在线阶乘计算器计算发现结果很大1.0813967582402912e+168。而int是32位,数据早已溢出,所以,用于存放阶乘结果的s要改成长整型long long int。

(2)再次尝试,发现依然运行超时。看来计算n阶乘占用的空间和时间都比较长。

(3)当我们尝试从1到n逐次计算n阶乘时,会发现一个规律,遇见能被5整除的数时,尾部0就可+1;而尾部的0一共有多少个,就要看这个数包含多少个5的因子。比如1到4的阶乘结果分别为1、2、6、24,5到9的阶乘结果是120、720、5040、40320、362880,10到14的结果分别是3628800、39916800、479001600、6227020800、87178291200,然后15!=1307674368000。也就是5有一个0,10有2个0,15有3个0,20有4个0,25有6个0,30有7个0等等,代码如下

long long trailingZeros(long long n) {
        // write your code here, try to do it without arithmetic operators.
        //计算n阶乘
        long long num = 0;
        long long temp=n;
        while(temp)
        {
            temp /= 5;
            num += temp;
        }
        
        return num;
    }

 结果

 

 值得注意的一件事就是,其中数据类型的定义,要是long long类型的,这一点题目在定义的时候函数结果上也有提示。

在线计算阶乘的地址http://www.99cankao.com/statistics/factorial-calculator.php

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值