与该题的缘分: 我在18年面试某大厂的笔试题
开始寻找有趣的规律, 如果阶乘中的某一位数是5
的整数倍, 则可以跟2
生成一个0
, 而2
的整数倍即偶数的数量很显然比5
的整数倍的数量多
5! -> 5 * 2 -> 1个零
10! -> 10 * (5 * 2) -> 2个零
15! -> (15 * 2) * 10 * (5 * 2) -> 3个零
20! -> 20 * (15 * 2) * 10 * (5 * 2) -> 4个零
25! -> (25 * 2) * 20 * (15 * 2) * 10 * (5 * 2) -> 5个零
30! -> 30 * (25 * 2) * 20 * (15 * 2) * (10) * (5 * 2) -> 6个零
35! -> (35 * 2) * 30 * (25 * 2) * 20 * (15 * 2) * (10) * (5 * 2) -> 7个零
40! -> 40 * (35 * 2) * 30 * (25 * 2) * 20 * (15 * 2) * (10) * (5 * 2) -> 8个零
45! -> (45 * 2) * 40 * (35 * 2) * 30 * (25 * 2) * 20 * (15 * 2) * (10) * (5 * 2) -> 9个零
50! -> 50 * (45 * 2) * 40 * (35 * 2) * 30 * (25 * 2) * 20 * (15 * 2) * (10) * (5 * 2) -> 10个零
那岂不是n
除以5
然后向下取整数就可以了
要考虑 25
可以拆分成 5 * 5
, 可以生成2
个零, 125
可以拆分成 5 * 5 * 5
可以生成3
个零, ...
5! -> 5 * 2 -> 5的1次方生成的1个零
10! -> 10 * (5 * 2) -> 5的1次方生成的2个零
15! -> (15 * 2) * 10 * (5 * 2) -> 5的1次方生成的3个零
20! -> 20 * (15 * 2) * 10 * (5 * 2) -> 5的1次方生成的4个零
25! -> (5 * 5 * 2 * 2) * 20 * (15 * 2) * 10 * (5 * 2) -> 5的1次方生成的5个零 + 5的2次方生成的1个零
30! -> 30 * (5 * 5 * 2 * 2) * 20 * (15 * 2) * (10) * (5 * 2) -> 5的1次方生成的6个零 + 5的2次方生成的1个零
35! -> (35 * 2) * 30 * (5 * 5 * 2 * 2) * 20 * (15 * 2) * (10) * (5 * 2) -> 5的1次方生成的7个零 + 5的2次方生成的1个零
40! -> 40 * (35 * 2) * 30 * (5 * 5 * 2 * 2) * 20 * (15 * 2) * (10) * (5 * 2) -> 5的1次方生成的8个零 + 5的2次方生成的1个零
45! -> (45 * 2) * 40 * (35 * 2) * 30 * (5 * 5 * 2 * 2) * 20 * (15 * 2) * (10) * (5 * 2) -> 5的1次方生成的9个零 + 5的2次方生成的1个零
50! -> (5 * 5 * 2 * 2) * (45 * 2) * 40 * (35 * 2) * 30 * (5 * 5 * 2 * 2) * 20 * (15 * 2) * (10) * (5 * 2) -> 5的1次方生成的10个零 + 5的2次方生成的2个零
再次寻找规律, 可以发现, 结果为n
除以5
的整数次幂向下取整之和
const res = Math.floor(n / 5) + Math.floor(n / (5 * 5)) + ...
var trailingZeroes = function (n) {
let init = 5
let res = 0
while (init <= n) {
res += Math.floor(n / init)
init *= 5
}
return res
}