阶乘函数后k个零

题目简介:

 f(x) 是 x! 末尾是 0 的数量。回想一下 x! = 1 * 2 * 3 * ... * x,且 0! = 1 。

例如, f(3) = 0 ,因为 3! = 6 的末尾没有 0 ;而 f(11) = 2 ,因为 11!= 39916800 末端有 2 个 0 。
给定 k,找出返回能满足 f(x) = k 的非负整数 x 的数量。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/preimage-size-of-factorial-zeroes-function

运用数学思想+二分查找。

首先一开始我就直接想去计算每个数的阶乘的值并判断其末尾有多个零,再就是想要用双层for循环去将其逐个遍历,现在想想这种方法实在是不可行。

接下来我开始深入思考:

        末尾为零简单就是需要一个末尾为5的数与一个偶数相乘可得,以及10的倍数。再找到它们的共同点就是它们的因子有5的存在,我们可以抽茧剥丝的发现只要找到有多少个因子5阶乘的末尾就有多少个零。那么再仔细思考一下这道题是需要找出满足末尾为k个零的非负整数的数量x,因此我们可以发现从5到10到15再到20这其中每五个数为一组,但到了25时,我们发现它一下子就从末尾零的个数4到6,这是因为25的因子5有两个。那么我们就可以发现最终的答案要么是0,要么是5,我们只要找到是否有那么多个因子等于k的值,等于答案即为5,不等于为0。

        二分法的使用需要时一个有序的排列,符合本题的要求,通过一系列数学公式进行缩放可以等到范围为【4k,5k】,因此我们只需要判断如k=1时判读4和5就行。

class Solution {
    public int preimageSizeFZF(int k) {
        if (k <= 1) return 5;
        return f(k) - f(k - 1);
    }
    int f(int x) {
        long l = 0, r = (long) 1e10;
        while (l < r) {
            long mid = l + r + 1 >> 1;
            if (getCnt(mid) <= x)

                        l = mid;
            else r = mid - 1;
        }
        return (int)r;
    }
    long getCnt(long x) {
        long ans = 0;
        while (x != 0) {
            ans += x / 5; x /= 5;
        }
        return ans;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值