leetCode第172题——阶乘后的零
Posted 小志的博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetCode第172题——阶乘后的零相关的知识,希望对你有一定的参考价值。
一、题目
给定一个整数 n ,返回 n! 结果中尾随零的数量。提示:0 <= n <= 10的4次幂
进阶:你可以设计并实现对数时间复杂度的算法来解决此问题吗?
示例 1:
输入:n = 3
输出:0
解释:3! = 6 ,不含尾随 0
示例 2:
输入:n = 5
输出:1
解释:5! = 120 ,有一个尾随 0
示例 3:
输入:n = 0
输出:0
二、题目代码解析(迭代法实现)
1、代码
public class Test1 {
public static void main(String[] args) {
int a=trailingZeroes(50);
System.out.println("阶乘后末尾为零的数量:【"+a+"】");
}
/**
* 迭代计算阶乘
*/
public static int trailingZeroes(int n){
//迭代方式计算阶乘
BigInteger nFactorial = BigInteger.ONE;
for (int i = 2; i <= n; i++) {
nFactorial = nFactorial.multiply(BigInteger.valueOf(i));
}
System.out.println("阶乘后的结果为:"+nFactorial);
//如果一个数字末尾有零,那么它可以被 10整除。除以 10将删除该零,并将所有其他数字右移一位。
//因此,我们可以通过反复检查数字是否可以被 1整除来计算末尾 0 的个数。
int zeroCount = 0;//阶乘后的结果中尾随零的数量初始值0
//阶乘后的数模10,取余数和0比较
while (nFactorial.mod(BigInteger.TEN).equals(BigInteger.ZERO)) {
//如果阶乘后的数模10取余数和0相等,把阶乘后的数除10
nFactorial = nFactorial.divide(BigInteger.TEN);
zeroCount++;//阶乘后的结果中尾随零的数量+1
}
return zeroCount;
}
}
2、结果如下图:
三、进阶(计算因子方式实现)
思路摘自此博文链接https://leetcode.wang/leetcode-172-Factorial-Trailing-Zeroes.html
1、思路
- 首先末尾有多少个 0 ,只需要给当前数乘以一个 10 就可以加一个 0。
- 再具体对于 5!,也就是 5 * 4 * 3 * 2 * 1 = 120,我们发现结果会有一个 0,原因就是 2 和 5 相乘构成了一个 10。而对于 10 的话,其实也只有 2 * 5 可以构成,所以我们只需要找有多少对 2/5。
- 我们把每个乘数再稍微分解下,看一个例子。
- 11! = 11 * 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 = 11 * (2 * 5) * 9 * (4 * 2) * 7 * (3 * 2) * (1 * 5) * (2 * 2) * 3 * (1 * 2) * 1
- 对于含有 2 的因子的话是 1 * 2, 2 * 2, 3 * 2, 4 * 2 …
- 对于含有 5 的因子的话是 1 * 5, 2 * 5…
- 含有 2 的因子每两个出现一次,含有 5 的因子每 5 个出现一次,所有 2 出现的个数远远多于 5,换言之找到一个 5,一定能找到一个 2 与之配对。所以我们只需要找有多少个 5。
- 直接的,我们只需要判断每个累乘的数有多少个 5 的因子即可。
2、思路进阶
- 对于一个数的阶乘,就如之前分析的,5 的因子一定是每隔 5 个数出现一次,也就是下边的样子。
- n! = 1 * 2 * 3 * 4 * (1 * 5) * … * (2 * 5) * … * (3 * 5) *… * n
- 因为每隔 5 个数出现一个 5,所以计算出现了多少个 5,我们只需要用 n/5 就可以算出来。但还没有结束,继续分析。
- … * (1 * 5) * … * (1 * 5 * 5) * … * (2 * 5 * 5) * … * (3 * 5 * 5) * … * n
- 每隔 25 个数字,出现的是两个 5,所以除了每隔 5 个数算作一个 5,每隔 25 个数,还需要多算一个 5。
- 也就是我们需要再加上 n / 25 个 5
- 同理我们还会发现每隔 5 * 5 * 5 = 125 个数字,会出现 3 个 5,所以我们还需要再加上 n / 125 。
- 综上,规律就是每隔 5 个数,出现一个 5,每隔 25 个数,出现 2 个 5,每隔 125 个数,出现 3 个 5… 以此类推。
- 最终 5 的个数就是 n / 5 + n / 25 + n / 125 …
- 写程序的话,如果直接按照上边的式子计算,分母可能会造成溢出。所以算 n / 25 的时候,我们先把 n 更新,n = n / 5,然后再计算 n / 5 即可。后边的同理。
3、代码
public class Test1 {
public static void main(String[] args) {
//int a=trailingZeroes(50);
int a=trailingZeroe(50);
System.out.println("阶乘后末尾为零的数量:【"+a+"】");
}
public static int trailingZeroe(int n) {
int count = 0;
while (n > 0) {
count += n / 5;
n = n / 5;
}
return count;
}
}
4、结果如下图:
以上是关于leetCode第172题——阶乘后的零的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 172 阶乘后的零[数学] HERODING的LeetCode之路
LeetCode 172. 阶乘后的零 / 682. 棒球比赛 / 2028. 找出缺失的观测数据