其他分享
首页 > 其他分享> > leetcode-172

leetcode-172

作者:互联网

题目

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

爆破

class Solution:
    def trailingZeroes(self, n: int) -> int:
        result = reduce(lambda x,y:x*y, [x for x in range(1, n+1)])
        count = 0
        while result % 10 == 0:
            count += 1
            result /= 10
        return count

遇见问题需要关注两个点

  • 问题究竟是什么
  • 方法究竟干什么

有时候,题干中有很多垃圾,它的作用只是用来进行误导,也可能毫无作用。

思考时,一方面可能受垃圾影响,导致范围扩大,一方面由于思想收束,丢失部分信息。

两个方面需要进行对比衡量,才能做到快速和准确。

规律

有多少个0,意味着能够阶段的被10整除,但是垃圾在于,我们是否一定需要n!

九真一假,才能骗到人。

有用的信息,不一定就能够直接用,n!并不很好用。

升华到10以后,我们可以看见,对于整体的判断可以分割到步骤中。

这样,重叠的两个部分采用同一个逻辑,必然更加快速。


根据这个思路,可以进行两层的深入

class Solution:
    def trailingZeroes(self, n: int) -> int:
        count_5 = 0
        for i in range(1, n+1):
            if i % 5 == 0:
                count_5 += 1
        return count_5

但是,25这种,隐含的多重的5的因子,需要多重的计算

25 × 2 = 50 25 = 5 × 5 25 \times 2 = 50 \\ 25 = 5 \times 5 25×2=5025=5×5

配对以后还能配对

class Solution:
    def trailingZeroes(self, n: int) -> int:
        count_5 = 0
        for i in range(1, n+1):
            while i % 5 == 0:
                count_5 += 1
                i //= 5
        return count_5

命中

其实有个很简单的道理,如果不是 5 5 5的倍数,必然不能被 5 5 5整除,不是 5 5 5的倍数,我们就不必要关注

class Solution:
    def trailingZeroes(self, n: int) -> int:
        count_5 = 0
        for i in range(0, n+1, 5):
            while i % 5 == 0:
                count_5 += 1
                i //= 5
        return count_5

这样,需要计算的数据大概就是原来的 1 5 \frac{1}{5} 51​了。

角度

什么时候会重复生成因子 5 5 5?

可以考察一下下面几组数据

也就是说,基础组的 5 5 5来源于步进的倍数,但是如果是 5 5 5次的 5 5 5步进,就会诞生多重的 5 5 5。


可以先来回顾两个简单问题

堆积
a a a a a a a a a a \begin{matrix} &a &\\ &a &a &\\ &a &a &a &\\ &a &a &a &a \end{matrix} ​aaaa​aaa​aa​a​
请问到了第 n n n行,总共会有多少个a

当然,我们的结论都是 ∑ i = 1 n i \sum_{i=1}^n i ∑i=1n​i,但主要的问题是,你从哪里看的,按照行,还是按照列。

你可以说它就是每一行的数量,也可以说是每一列的数量,每一列的应该是
∑ i = 1 n ( n − i + 1 ) \sum_{i=1}^n (n-i+1) i=1∑n​(n−i+1)
两种思路在这道题中是一致的,但是第一种并不具备拓延性,接下来拓展一下


x n = { x x = 1 x × x n − 1 o d d ( x n 2 ) 2 e v e n x^n = \left\{ \begin{matrix} x & x = 1 \\ x \times x^{n-1} & odd \\ (x^{\frac{n}{2}})^2 & even \end{matrix} \right. xn=⎩⎨⎧​xx×xn−1(x2n​)2​x=1oddeven​
想象一下,这会让我们操作降低多少,基本上就是操作减半,也就是 O ( lg ⁡ n ) \Large O(\lg n) O(lgn)

但是,关注一下它的跨度,列举一下

它把每次的逐渐进行翻倍,但是最终结果是保留的。


现在,回顾一下初心,我们需要计算的是因子 5 5 5的个数,它也应该有层级的划分

根据 n n n,我们可以知道一层因子 5 5 5的数量是 n / / 5 n // 5 n//5。

二级因子呢,也就是以一级的 5 5 5的一组的 5 5 5的步进,三级四级依次递增。

这就很好的揭示了为什么有些数字会显得比较特殊,有多层的 5 5 5,因为他们的重复次数存在叠加。

class Solution:
    def trailingZeroes(self, n: int) -> int:
        if n < 5:
            return 0
        return (n // 5) + self.trailingZeroes(n // 5)

使用递归,分别计算每一层的 5 5 5的周期即可。

标签:count,25,return,int,trailingZeroes,172,因子,leetcode
来源: https://blog.csdn.net/wait_for_eva/article/details/113753949