172. 阶乘后的零— —力扣每日一题
172. 阶乘后的零— —2022/3/25
1、题目
给定一个整数 n
,返回 n!
结果中尾随零的数量。
提示 n! = n * (n - 1) * (n - 2) * ... * 3 * 2 * 1
2、示例
1)示例1
输入:n = 3
输出:0
解释:3! = 6 ,不含尾随 0
2)示例2
输入:n = 5
输出:1
解释:5! = 120 ,有一个尾随 0
3)示例3
输入:n = 0
输出:0
3、解答
3.1 思路及具体操作
- 初步的思路还是计算出阶乘之后的数,来计算0的个数
- 由于
java
给出的基本数据类型最大的长度也仅仅很小,所以不能直接使用基本数据类型去做 - 这里想的初步思路是使用
数组+字符串
的方式计算阶乘的值 - 计算的值也是使用数组去保存
trailingZeroes(int n)
计算0的个数transform(int n)
将整数转换成整型数组factorial(int n)
计算n!
的值factorials(int[] m,int[] n)
计算m
与n
的乘积
3.2 代码
/*本方法采用数组保存阶乘的数据,然后根据数组判断0的个数
* 虽然解决了办法,但是超出了时间限制,很难受
* */
public class Solution {
public static void main(String[] args) {
int[] arr = factorial(100);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]);
}
System.out.println("\n"+arr.length);
System.out.println(trailingZeroes(100));
}
//判断n阶乘0的个数
public static int trailingZeroes(int n) {
if(n == 0){
return 0;
}
int m = 0;
int[] intArr = factorial(n);
for (int i = intArr.length -1; i >= 0; i--) {
if(intArr[i] == 0){
m++;
}else{
break;
}
}
return m;
}
//整型转换成数组
public static int[] transform(int n){
String ms = "" + n + "";
char[] msc = ms.toCharArray();
int[] intArr = new int[msc.length];
for (int i = 0; i < msc.length; i++) {
intArr[i] = (int) msc[i] - 48;
}
return intArr;
}
//用数组保存阶乘的数据
public static int[] factorial(int n){
int nums = n;
int[] result = new int[n];
int num = n;
for (int i = 0; i < nums; i++) {
if(i==0){
result = factorials(transform(num),transform(num-1));
num --;
}else{
if(num == 1){
break;
}
num --;
result = factorials(result,transform(num));
}
}
int a = 0;
int b = 0;
for (int i = 0; i < result.length; i++) {
if(result[i] != 0){
a = result.length - i;
b = i;
break;
}
}
int[] results = new int[a];
for (int i = 0; i < a; i++) {
results[i] = result[b+i];
}
return results;
}
//返回两个数相乘的结果,返回结果为数组
public static int[] factorials(int[] m,int[] n) {
int result[] = new int[m.length+n.length];
for(int i = 0; i < m.length; i++){
for(int j = 0; j < n.length; j++){
result[result.length-1-i - j] += (m[m.length-1-i] * n[n.length-1-j])%10;
result[result.length-i - j - 2] += (m[m.length-1-i] * n[n.length-1-j])/10;
}
}
return result;
}
}
3.3 思考
- 其实计算出阶乘的值这个方法是由于想要再练习一下阶乘的计算,所以采用的直接法做
- 但是本题的实质其实是计算尾部 0 的个数,因此只需要明白什么样的值才能使得尾部可以为0
4、优化解法
4.1 优化思路
- 尾部 0 的产生是由于 10 的出现,所以只需要判断乘数中会出现的 10 的个数就可以判断出尾部 0 的个数
- 那我们就需要知道 10 可以是 5 与 2 的乘积,所以可以采用判断 5 的个数(所有5的公倍数相当于
5*公倍数
个5) - 因为5在2之后,所以不需要考虑 2 的个数问题
4.2 代码
public static int trailingZeroes(int n) {
int num = 0;
for (int i = 5; i <= n; i+=5) {
for (int x = i; x % 5 == 0; x /= 5) {
num++;
}
}
return num;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET10 - 预览版1新功能体验(一)