LINTCODE:172 阶乘后的零(Python语言实现)

版权声明:转载请联系博主 https://blog.csdn.net/Watkins_OS/article/details/83244384

1. 题目描述

给定一个整数n,返回n!结果尾数中零的数量。

说明:

你算法的时间复杂度应为O(log n)

示例1:

输入:3

输出:0

解释:3! = 6,尾数中没有零。

示例2:

输入:5

输出:1

解释:5! = 120,尾数中有1个零。

2. 朴素法求解

顾名思义,可以先求出阶乘,再利用对10的求余来作为次数累加的循环条件。但是时间复杂度不符合要求,经测试,为“时间超时”。

class Solution(object):
    def trailingZeroes(self, n):
        """
        :type n: int
        :rtype: int
        """
        fact = 1
        for i in range(2, n+1):
            fact *= i
        rcnt = 0
        while fact%10 == 0:
            rcnt += 1
            fact //= 10
        return rcnt

3. 进一步优化

要使得尾数为0,其中必然会有5的倍数的存在。每逢一个5的出现,前面就会有偶数的存在,所以不需要考虑偶数的因素。数字递增的过程中会发现,凡5的累积倍数均生成数个0,比如25,可以拆分成两个5。这里,直接对n逢五递增,并对每一个5的倍数进行拆分,而且累加次数。经测试,显示“内存不足”。

class Solution(object):
    def trailingZeroes(self, n):
        """
        :type n: int
        :rtype: int
        """
        rcnt = 0
        for i in range(5, n+1, 5):
            cur = i
            while cur%5 == 0:
                rcnt += 1
                cur //= 5
        return rcnt

原因在于,range所产生的列表,在遇到百万级的数字时会超出其限制大小。所以考虑将for循环改写成while循环避免这种情况。经测试,显示“时间超时”。

class Solution(object):
    def trailingZeroes(self, n):
        """
        :type n: int
        :rtype: int
        """
        rcnt = 0
        while n >= 5:
            cur = 5 * (n/5)
            while cur%5 == 0:
                rcnt += 1
                cur //= 5
            n -= 5
        return rcnt

4. 分析规律

要在不大于n的范围内寻找5的简单倍数以及5的累计倍数次数,可以分解成两个部分。第一部分,5的简单倍数,可以直接整除5就可以得到;第二部分,5的累计倍数次数,可采用前面的除值的结果除以5,依次递归下去,直到为0。比如:75除以5得15,即存在15个5的简单倍数,再利用15除以5得3,即3个5的累计倍数次数为2的值,分别是25、50、75。经测试,显示“通过”。

class Solution(object):
    def trailingZeroes(self, n):
        """
        :type n: int
        :rtype: int
        """
        rcnt = 0
        while n > 0:
            n //= 5
            rcnt += n
        return rcnt

其递归格式为:

class Solution(object):
    def trailingZeroes(self, n):
        """
        :type n: int
        :rtype: int
        """
        if n == 0:
            return 0
        else:
            return (n//5) + self.trailingZeroes(n//5)

猜你喜欢

转载自blog.csdn.net/Watkins_OS/article/details/83244384