1. 问题背景与核心挑战
这道LeetCode 793题看似简单,实则暗藏玄机。题目要求我们找到满足阶乘结果末尾恰好有K个零的所有非负整数n的数量。换句话说,给定K值,我们需要确定有多少个n满足factorial(n)末尾的零的数量等于K。
阶乘末尾零的数量问题在计算机科学和数学中是一个经典问题。每个零实际上代表一个10的因子,而10=2×5。由于在阶乘中2的数量远多于5的数量,因此零的数量实际上取决于5的因子数量。例如:
- 5! = 120 → 1个零(包含1个5因子)
- 10! = 3628800 → 2个零(包含2个5因子)
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 数学原理与零计数算法
2.1 零数量的计算方法
计算n!末尾零的数量,本质上是计算1到n所有数字中5的因子总数。这里有个高效的算法:
python复制def trailingZeroes(n: int) -> int:
count = 0
while n > 0:
n = n // 5
count += n
return count
这个算法的原理是:
- 首先计算有多少个数是5的倍数(贡献至少一个5)
- 然后计算有多少个数是25的倍数(贡献额外的5)
- 接着计算125的倍数,以此类推
2.2 零数量的单调性观察
关键观察点:trailingZeroes(n)是一个单调不减函数。这意味着:
- 当n增加时,零的数量要么不变,要么增加
- 这使得我们可以使用二分查找来高效定位特定K值对应的n范围
3. 二分查找算法设计
3.1 搜索范围的确定
我们需要找到所有满足trailingZeroes(n) == K的n。由于函数的单调性,这些n必然构成一个连续区间。因此问题转化为:
- 找到最小的n使得trailingZeroes(n) == K(左边界)
- 找到最大的n使得trailingZeroes(n) == K(右边界)
- 右边界 - 左边界 + 1 就是答案
3.2 二分查找实现细节
python复制def preimageSizeFZF(K: int) -> int:
def left_bound(K):
low, high = 0,
