LeetCode.H793
题目:
题目大意:
给定一个k,求有几个数的阶乘的最后k位是0。
数据范围:
如图所示
前置知识:
n的阶乘 n! 的末尾有几个0:【LeetCode.M172.阶乘后的零】
思路:
我们要想求 有几个数的阶乘的最后k位是0,不妨设 f(k) 为阶乘的末尾0的个数 <= k 的数,则f(k - 1) 为阶乘的末尾0的个数 <= k - 1 的数,则所求的阶乘的最后k位是0的数的个数为 f(k) - f(k - 1)。
那么问题变成了如何求f(k)。我们可知,随着一个数x的增大,其阶乘x! 的末尾0的个数 是单调非减的,所以可以使用【二分】来求得 f(k)。
二分时,左区间性质为x!的末尾0的个数小于等于k,则所求的左区间的右端点即为f(k), 初始 l = 0,r = 1e10。
r = 1e10,因为k的范围为0-1e9,为了保证二分的区间 [l, r] 能覆盖到所有阶乘末尾为k个0的数,r 应大于 5*k。
代码:
class Solution {
public long getCnt(long n){
long ans = 0;
while (n != 0){
n /= 5;
ans += n;
}
return ans;
}
public long f(long x){
long l = 0, r = (long) 1e10;
while (l < r){
long mid = l + r + 1 >> 1;
if (getCnt(mid) <= x)
l = mid;
else
r = mid - 1;
}
return l;
}
public int preimageSizeFZF(int k) {
if (k == 0)
return 5;
return (int) (f(k) - f(k - 1));
}
}
public class Main {
public static void main(String[] args) {
Solution solution = new Solution();
System.out.println(solution.preimageSizeFZF(1000000000));
}
}
时空复杂度分析等:
-
时间复杂度 : O((logk)^2)
-
空间复杂度 : O(1)