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)计算mn的乘积

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;
}
posted @   曦月宇望  阅读(46)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示