给定一个整数 n ,返回 n! 结果中尾随零的数量。
提示 n! = n * (n - 1) * (n - 2) * … * 3 * 2 * 1
示例 1:
输入:n = 3
输出:0
解释:3! = 6 ,不含尾随 0
示例 2:
输入:n = 5
输出:1
解释:5! = 120 ,有一个尾随 0
示例 3:
输入:n = 0
输出:0
提示:
- 0 <= n <= 104
进阶:你可以设计并实现对数时间复杂度的算法来解决此问题吗?
思路:n! 尾零的数量即为 n! 中因子 10 的个数,而 10=2×5,因此转换成求 n!中质因子 2 的个数和质因子 5 的个数的较小值。
在计算阶乘中尾随零的数量时,我们关注的是5的因子的数量,而不是10的因子的数量。这是因为每个10可以由一个5和一个2相乘得到,而每个5可以独立地产生一个尾随零。在阶乘的计算过程中,2的因子的数量通常比5的因子的数量多,因此我们只需要关注5的因子的数量。
int trailingZeroes(int n) {
int res = 0;
while (n>0) {
n/=5;
res+=n;
}
return res;
}
为什么使用5,而不是使用2呢?
要计算一个数的阶乘(n!)末尾有多少个零,我们只需要关心阶乘中因子 2 和 5 的对数,因为 2 和 5 相乘会产生一个 10,从而在末尾增加一个零。
然而,当我们考虑从 1 到 n 的所有整数的阶乘时,因子 2 的数量通常远大于因子 5 的数量。这是因为除了 5 的倍数,还有 25、125、625 等的倍数也会贡献额外的 5 的因子(例如,25 包含两个 5 的因子,125 包含三个 5 的因子,以此类推)。但与此同时,任何整数都至多包含一个 2 的因子(除了 2 的幂次方,但这些不会增加额外的 5 的因子)。
因此,当我们计算 n! 中 2 和 5 的因子对数时,我们总是会遇到足够的 2 的因子来与 5 的因子配对,从而产生末尾的零。所以,为了找到 n! 末尾零的数量,我们只需要计算 n! 中包含多少个 5 的因子即可。这是因为 5 的因子是限制性的因子,决定了我们可以形成多少对 2 和 5 来产生末尾的零。