【力扣roadmap】793. 阶乘函数后 K 个零

17 阅读1分钟

题目描述

  • 竞赛积分2100
  • 题号793

image.png

思路

我们画一个数轴,如下图所示,显然<=x的数字的阶乘进行质因数分解,5的个数都必然小于等于k。

image.png

本题要求给出f(x)=k,满足条件的x的数量,所以对应到我们的cal的定义,本题的答案应该是cal(k)-cal(k-1),直白点解释:阶乘分解出5的个数小于等于k个元素个数,减去阶乘分解出5的个数小于等于k-1的元素个数,就是阶乘分解的5的个数等于k的元素个数

cal用代码怎么实现?如何计算x!质因数分解后5的个数?x!的质因数分解中,5,10,15,20之类的数字分别贡献了一个5,但是特别的:25贡献了两个5,125贡献了3个5,以此类推。所以x!的质因数分解的5的个数cnt(x)为

cnt(x)=x5+x25+x125+cnt(x) = \frac{x}{5} + \frac{x}{25} + \frac{x}{125} + \cdots \\
cnt(x)=x5+x515+x51515+ cnt(x) = \frac{x}{5} + \frac{x}{5} * \frac{1}{5} + \frac{x}{5} * \frac{1}{5} * \frac{1}{5} + \cdots

因此计算x!的质因数分解的5的个数的代码,如get_cnt所示。

代码

class Solution:
    def preimageSizeFZF(self, k: int) -> int:
        # 给定 k,找出返回能满足 f(x) = k 的非负整数 x 的数量。
        return self.cal(k) - self.cal(k-1) 

    # 定义函数 y = cal(x) 如下
    # 将y进行因式分解,得到5的个数恰好小于等于x个(y+1就能分解出更多5)
    # 显然 <= y 的数字,其分解出来的5的个数都小于等于x个 
    def cal(self,x) :
        l , r = 0 , int(5e9+10)
        while l < r :
            mid = l + (r - l) // 2
            if self.get_cnt(mid) > x :
                r = mid 
            else :
                l = mid + 1
        return l
    
    def get_cnt(self,x) :
        ans = 0
        while x > 0 :
            ans += x // 5 
            x //= 5 
        return ans