每天学习一点算法 2026/04/08
题目:阶乘后的零
给定一个整数
n,返回n!结果中尾随零的数量。提示
n! = n * (n - 1) * (n - 2) * ... * 3 * 2 * 1
我们先来分析一下,什么情况下有阶乘结果末尾会有 0 , 因为 2 * 5 = 10,所以这道题就可以转换成求阶乘中有多少个 2 * 5
我们这里想到最简单的办法就是统计所有数字的 2 和 5 的因数的个数,然后取较小的一个
再有我们其实可以知道每个五的倍数和它相邻五的倍数之间至少有两个偶数,所以因数 5 的个数一定是小于 2 的个数的,所以我们可以直接统计因数 5 的个数返回
typescript
function trailingZeroes(n: number): number {
if (n < 5) return 0
let count5 = 0
for (let i = 5; i <= n; i++) {
if (i % 5 !== 0) {
continue
}
let current = i
while (current % 5 === 0) {
count5++
current /= 5
}
}
return count5
};
那么我们可以设计并实现对数时间复杂度的算法来解决此问题吗?
其实上面的问题就转变成了,小于 n 的 5 的倍数中因数 5 的个数
- 我先计算一下 5 的倍数就应该是:
m = Math.floor(n / 5) - 我们注意到每出现第五次 5 的倍数就会出现一个 包含因数 5 的 5 的倍数:
o = Math.floor(m / 5) - ...
我们其实这个过程就是:先找 5 的 1 次幂的个数,再找 5 的 2 次幂的个数,直到找 5 的 i 次幂的个数(5 的 i + 1 次幂 大于 n)
我们将这写数累加起来就是我们要找的因数 5 的个数
typescript
function trailingZeroes(n: number): number {
let sum = 0
while (n >= 5 && n !== 0) {
n = Math.floor(n / 5)
sum += n
}
return sum
};
题目来源:力扣(LeetCode)