[leetcode]阶乘后的零

283 阅读2分钟

image.png

与该题的缘分: 我在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然后向下取整数就可以了

image.png

要考虑 25 可以拆分成 5 * 5, 可以生成2个零, 125可以拆分成 5 * 5 * 5可以生成3个零, ...

 5!  -> 5 * 2 -> 51次方生成的1个零
 10! -> 10 * (5 * 2) -> 51次方生成的2个零
 15! -> (15 * 2) * 10 * (5 * 2) -> 51次方生成的3个零
 20! -> 20 * (15 * 2) * 10 * (5 * 2) -> 51次方生成的4个零
 25! -> (5 * 5 * 2 * 2) * 20 * (15 * 2) * 10 * (5 * 2) -> 51次方生成的5个零 + 52次方生成的1个零
 30! -> 30 * (5 * 5 * 2 * 2) * 20 * (15 * 2) * (10) * (5 * 2) -> 51次方生成的6个零 + 52次方生成的1个零
 35! -> (35 * 2) * 30 * (5 * 5 * 2 * 2) * 20 * (15 * 2) * (10) * (5 * 2) -> 51次方生成的7个零 + 52次方生成的1个零
 40! -> 40 * (35 * 2) * 30 * (5 * 5 * 2 * 2) * 20 * (15 * 2) * (10) * (5 * 2) -> 51次方生成的8个零 + 52次方生成的1个零
 45! -> (45 * 2) * 40 * (35 * 2) * 30 * (5 * 5 * 2 * 2) * 20 * (15 * 2) * (10) * (5 * 2) -> 51次方生成的9个零 + 52次方生成的1个零
 50! -> (5 * 5 * 2 * 2) * (45 * 2) * 40 * (35 * 2) * 30 * (5 * 5 * 2 * 2) * 20 * (15 * 2) * (10) * (5 * 2) -> 51次方生成的10个零 + 52次方生成的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
}

image.png

image.png