思路:
思路一
暴力模拟
使用BigInteger,因为阶乘后的数太大
int型有10位数
−2147483648−2147483648 至 21474836472147483647,
long型有19位数,相当于20位数
−9223372036854775808 至 92233720368547758079223372036854775807
如果发现大于这个数就要考虑使用BigInteger
for循环算出阶乘,将算出来的阶乘转化成String 字符型,再将字符型转换成char型数组,从后向前判断有几个'0'即有几个尾随零。
但是题目中要
算法效率低下,这个写法是为了复习BigInteger的使用,如果是填空题可以使用,快速解决问题。
BigInteger中的1的用法有BigInteger.ONE,
BigInteger.valueOf(i)中的i不能超过long型,否则报错,BigInteger的原因
import java.math.BigInteger;
import java.util.Scanner;
public class 阶乘尾随零 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
BigInteger sum=BigInteger.ONE;
int ans=0;
if(n!=0){
for(int i=1;i<=n;i++){
sum=sum.multiply(BigInteger.valueOf(i));
}
String a=sum+"";
char[]arr=a.toCharArray();
for(int i=arr.length-1;i>=0;i--) {
if(arr[i]=='0') {
ans++;
}else {
break;
}
}System.out.println(ans);
}else{
//return 0;
System.out.println(0);
}
}
}
思路二数论:
数学知识,每个尾随的零都是由10的倍数贡献的,而10可以分解为2和5的乘积。因此,在阶乘中,每对2和5的组合就会产生一个10,从而增加一个尾随零。为什么只需要统计5的数量。因为在阶乘的质因数分解中,2的数量远多于5。例如,10!中,质因数2的出现次数是8次(在2、4、6、8、10中),而5的出现次数是2次(在5和10中)。因此,2的数量足够多,所以尾随零的数量由5的数量决定。
举例:25的阶乘后又几个零?
生成零的条件是阶乘运算时相乘有10的倍数的生成,
只有5和一个偶数相乘会得到10或10的倍数,所以有几个5就有几个10,就有几个0
每个5与一个偶数相乘便可得到一个10的倍数 ,偶数的个数比5多。
2*5,2*10=2*5*2, 2*15=2*5*3, 2*20=2*5*4, 2*25=2*5*5(要再来一个偶数与多的5进行相乘); 中5出现了6次
因此要计算5出现的个数就是尾随零的个数。
class Solution {
public int trailingZeroes(int n) {
int count=0;
while(n>1) {
n/=5;
count+=n;
}
return count;
}
}
阶乘中每个数贡献的5因子数量可分为多个层级:
- 基础贡献:所有能被5整除的数至少贡献 1个5因子,如5、10、15等。
- 高阶贡献:能被25(5²)整除的数额外贡献 1个5因子,如25=5×5贡献2个,但第一次除以5时只算到1个,需额外加一次。
- 更高阶贡献:如125(5³)、625(5⁴)等,每层贡献对应次数的额外5因子。
示例:以n=125为例:
- 第一次计算:125/5=25 → 基础贡献25个5因子(对应5,10,…,125)。
- 第二次计算:125/25=5 → 高阶贡献5个5因子(对应25,50,…,125)。
- 第三次计算:125/125=1 → 更高阶贡献1个5因子(对应125)。
- 总计:25+5+1=31个零。