leetcode
leetcode 2801 ~ 2850
阶乘尾数

阶乘尾数

难度:

标签:

题目描述

Write an algorithm which computes the number of trailing zeros in n factorial.

Example 1:

Input: 3
Output: 0
Explanation: 3! = 6, no trailing zero.

Example 2:

Input: 5
Output: 1
Explanation: 5! = 120, one trailing zero.

Note: Your solution should be in logarithmic time complexity.

代码结果

运行时间: 21 ms, 内存: 16.1 MB


/*
  题目思路:
  使用 Java Stream 的方法实现相同的逻辑。
  主要是通过流的方式计算从 5 到 n 的每一个 5 的倍数的数量。
*/
import java.util.stream.Stream;
public class Solution {
    public int trailingZeroes(int n) {
        return Stream.iterate(5, i -> i <= n, i -> i * 5)
                     .mapToInt(i -> n / i)  // 计算每个 5 的倍数因子数量
                     .sum();  // 汇总所有的因子数量
    }
}

解释

方法:

题解的思路是计算阶乘中尾随零的数量。尾随零是由因子10产生的,而10可以分解为2和5。在阶乘数中,因子2的数量总是多于因子5的数量,因此尾随零的数量由因子5的数量决定。题解通过循环减少n的值,每次将n除以5,并累加结果到ans中。这样可以计算出包含在n!中的所有5的因子的总数,从而得到尾随零的数量。

时间复杂度:

O(log n)

空间复杂度:

O(1)

代码细节讲解

🦆
为什么在计算阶乘尾数中零的数量时,只需要关注因子5的数量而不是因子2的数量?
在计算阶乘数的尾随零时,每个零都来源于因子10,而10可分解为2和5。在任何阶乘数中,因子2的出现频率总是高于因子5,因为每隔一个数就有一个偶数,从而提供了一个因子2。这意味着因子2不会成为限制尾随零数量的因素。相对而言,因子5较少,因此决定了尾随零的数量。只要统计因子5的数量,就可以确定阶乘结果尾随零的数量。
🦆
在算法中,每次将n除以5并累加的过程是如何确保计算了所有可能的包含5的因子的情况?
这个算法通过不断地将n除以5并累加结果的方式,能够有效地计算出阶乘数中所有的5的因子。初始的除以5是为了找出n以内直接被5整除的数字(每一个都贡献一个5作为因子)。然后,再除以5是为了找出被25整除的数字(每一个都贡献额外的一个5因为25=5x5),依此类推。这样可以确保所有5的幂的贡献都被计入,从而准确地统计出所有可能的含5的因子。
🦆
在实际应用中,这种方法处理非常大的n(例如10^9级别)时是否依然有效?有没有可能的性能瓶颈?
这种方法在处理非常大的n时依然有效且效率较高。算法的时间复杂度主要取决于对n连续除以5的次数,这是一个对数级别的操作(基于5的对数)。例如对于n=10^9,最多需要进行大约log5(10^9)约等于13次的迭代,这在计算上是非常快速的。因此,对于非常大的数,这个算法仍然可以在非常短的时间内得出结果,没有明显的性能瓶颈。

相关问题