阶乘尾部的0
每天一道算法题
问题
- 描述:
- 设计一个算法,计算出 n 阶乘中尾部 0 的个数。(不考虑 n = 0)
- 挑战:
- O(logN)的时间复杂度
解决
首先我们不考虑时间复杂的解决思路是先求出 n 的阶乘,然后再计算 n 阶乘尾部 0 的个数。
代码如下:
public long trailingZeros(long n) {
long arg = 1;
long result = 0;
//求 n 的阶乘
for (int i = 2; i <= n; i++) {
arg *= i;
}
//求尾部 0 的个数
while (arg % 10 == 0) {
if (arg == 0) {
return result;
}
++result;
arg /= 10;
}
return result;
}
时间复杂度为 O(N)。那如何才能使时间复杂度为 O(logN) 呢?
先求阶乘,然后再求尾部 0 的个数肯定不行。所以我们必须找出 n 与 n 阶乘尾部 0 的个数之间的关系。
我们将 n 阶乘中每个数拆成素因子的乘积,发现尾部的 0 是由 2*5 产生的,而 5 的量一定小于 2,因此素因子中 5 的个数决定了尾部 0 的个数,只要求出 n 阶乘中素因子 5 的出现次数即可。
11 ! = 11 * 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1
= 11 * 2*5 * 3*3 * 2*2*2 * 7 * 2*3 * 5 * 2*2 * 3 * 2 * 1 (其中素因子 5 有 2 个)
= 39916800 (尾部有 2 个 0)
代码如下
public long trailingZeros(long n) {
long result = 0;
while (n >= 5) {
n /= 5;
result += n;
}
return result;
}
| 原文请点击 |
|---|

浙公网安备 33010602011771号