2021/04/12
解法一
因子 5 的个数一定比 2 多,所以只需要统计有多少个 5
考察 28 的阶乘:
5 10 15 20 25
1 1 1 1 2
一共有 6 个 5,所以结尾有 6 个零。
impl Solution {
pub fn trailing_zeroes(n: i32) -> i32 {
let mut zero = 0;
for mut fac_5 in (5..=n).step_by(5) {
while fac_5 % 5 == 0 {
fac_5 /= 5;
zero += 1;
}
}
return zero;
}
}
解法二
每隔 5 个数有 1 个因子 5 ($\frac{n}{5}$个)
每隔 25 个数有 2 个因子 5 ($\frac{n}{25}$个, 这里不用乘以$2$,因为$\frac{n}{5}$的时候算过一遍)
每隔 125 个数有 3 个因子 5 ($\frac{n}{125}$个,这里不用乘以$3$,因为$\frac{n}{5}$的时候算过一遍,$\frac{n}{25}$的时候算过一遍)
…
impl Solution {
pub fn trailing_zeroes(mut n: i32) -> i32 {
let mut zero = 0;
while n > 0 {
zero += n / 5;
n /= 5;
}
return zero;
}
}
解法二的筛法理解
我们要求的是 n! 分解质因数后 5 的指数。
第一轮,我们先把 1~n 中所有能被 5 整除的数筛出来,可以筛出$\lfloor\frac{n}{5}\rfloor$个数。
第二轮,我们把上一轮筛除来的所有的数都除以 5,得到了一个新数组,这个新数组中可能还有一些数是 5 的倍数(没筛干净),那么重复第一轮的方式筛出来,直到第二轮筛不出 5 的倍数为止。
解法二的子问题理解
我们定义$f(n)$为整数$n$分解质因数后$5$的指数。
那么
这样,我们就把 $f(n!)$ 变成了 $f(\lfloor\frac{n}{5}\rfloor!)$ 这个子问题。