【lintcode】2.尾部的零(c/c++/python解法)

题目

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

输入: 11
输出: 2
样例解释: 
11! = 39916800, 结尾的02个。

样例 2:

输入:  5
输出: 1	
样例解释: 
5! = 120, 结尾的01个。

挑战
O(logN)的时间复杂度

1.c++/c解法

第一次

想法是通过向十取余来计算零的个数

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) 
    {
       
        int t=0,s=1;
        for(int i = 1 ;i <= n ; i++)
        {
            s *= i;
        }
        while(s%10 == 0)
        {
            t++;
            s /= 10;
        }
        return t;
    }
};

第一次测试数据通过了,但是提交失败。测试数据达到12阶乘以上全部失败,而且运行时间超时。打算颠倒数字重头开始计算零的数字

long long trailingZeros(long long n)
    {

        int t=0,s=1;
        int r[150000];
        for(int i = 1 ;i <= n ; i++)
        {
            s *= i;
        }
        while(s != 0)
        {
            r[t] = s % 10;
            t++;
            s /= 10;
        }
        int len = 0;
        for(;r[len]==0;len++)
        {
            if(r[len]!=0)
                break;
        }
        return len;
    }

再一次失败后觉得是数组长度问题,修改数组长度后还是错误。于是觉得是算法问题,不能用数组存放。于是直接每颠倒一位数字便进行判断:

   long long trailingZeros(long long n)
    {

        int t=0,s=1;
        for(int i = 1 ;i <= n ; i++)
        {
            s *= i;
        }
        int len=0;
        while(s != 0)
        {
            int r;
            r = s % 10;
            if(r==0)
                {
                    len++;
                }
            else break;
            t++;
            s /= 10;
        }
       
        return len;
    }

发现这样的方法还是错误,发现是存放阶乘结果的s长度不够。于是修改为long long int 定义s。结果还是失败,于是开始反思算法。

修改版算法

可以将每个数拆分成其素因子的乘积,可以发现,0是由2*5产生的,而5的数量一定小于2的数量,因此5的个数决定了结尾0的个数。
只要计算n的阶乘中,5这个素因子出现多少次即可。

class Solution {
public:
    // param n : description of n
    // return: description of return 
    long long trailingZeros(long long n) {
        long long sum = 0;
        while (n != 0) {
            sum += n / 5;
            n /= 5;
        }
        return sum;
    }
};

或者是:

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 numFactor5 = 0;
        
        while (n >= 5)
        {
            n = n / 5;
            numFactor5 += n;
        }

        return numFactor5;
    }
};

python解法

可以将每个数拆分成其素因子的乘积,可以发现,0是由2*5产生的,而5的数量一定小于2的数量,因此5的个数决定了结尾0的个数。
只要计算n的阶乘中,5这个素因子出现多少次即可。

class Solution:
    # @param n a integer
    # @return ans a integer
    def trailingZeros(self, n):
        sum = 0
        while n != 0:
            n /= 5#这里可以替换为n //= 5(//代表抹除小数部分取整数)
            sum+= n
        return sum

说实话,这种方法不太会。

发布了14 篇原创文章 · 获赞 26 · 访问量 4287

猜你喜欢

转载自blog.csdn.net/m0_46976252/article/details/105523371