📜  在将n个数字相乘后找到末尾的连续零个数字(1)

📅  最后修改于: 2023-12-03 15:08:01.376000             🧑  作者: Mango

在将n个数字相乘后找到末尾的连续零个数字

在计算机编程中,求一个数的阶乘时,需要将从1到该数的所有整数相乘。在这个过程中,若是有一个数是5的倍数,那么结果就会多一个0;若是有一个数是25的倍数,那么结果就会多两个0……依此类推。

对于一个数 $n$,其阶乘的结尾会有相应的 $0$ 的个数。如何求出 $n!$ 结尾有多少个 $0$ 呢?

不难发现,$n!$ 结尾有 $k$ 个 $0$,当且仅当 $n!$ 能够被 $10^k$ 整除,而 $10^k$ 可以表示为 $2^k * 5^k$,所以 $n!$ 有 $k$ 个 $0$ 的条件为:$n!$ 能够被 $2^k$ 和 $5^k$ 整除。

在 $n!$ 中,5 的倍数的个数要比 2 的倍数的个数要少,所以只要统计其中 5 的倍数的个数,就可以知道 $n!$ 结尾的 $0$ 的个数。

因此,可以通过以下算法来求解 $n!$ 的末尾连续的 $0$ 的个数。

代码实现
def trailing_zeros_in_factorial(n: int) -> int:
    """
    给定一个正整数 n,返回 n! 结尾的 0 的个数。

    Parameters:
        n (int): 正整数

    Returns:
        int: n! 结尾的 0 的个数
    """

    # 5 的个数
    count = 0

    # 假设 n = 25,那么在结果中有 5, 10, 15, 20, 25 共 5 个 5 的因子,在结果中会产生 6 个 0。
    # 同样的,在 n >= 5 的情况下,n 可以被拆分成若干个 5 的倍数。
    # 需要注意的是,25, 125, 625, ... 等值也是 5 的倍数,需要特殊处理。
    while n >= 5:
        count += n // 5
        n //= 5

    return count

上述算法的时间复杂度为 $O(\log n)$,空间复杂度为 $O(1)$。

测试样例
assert trailing_zeros_in_factorial(3) == 0
assert trailing_zeros_in_factorial(5) == 1
assert trailing_zeros_in_factorial(10) == 2
assert trailing_zeros_in_factorial(25) == 6
assert trailing_zeros_in_factorial(100) == 24

这样,我们就能够顺利地求解 $n!$ 的末尾连续的 $0$ 的个数了!