leetcode 793. Preimage Size of Factorial Zeroes Function

9 篇文章 0 订阅
3 篇文章 0 订阅

Let f(x) be the number of zeroes at the end of x!. (Recall that x! = 1 * 2 * 3 * ... * x, and by convention, 0! = 1.)

For example, f(3) = 0 because 3! = 6 has no zeroes at the end, while f(11) = 2because 11! = 39916800 has 2 zeroes at the end. Given K, find how many non-negative integers x have the property that f(x) = K.

Example 1:
Input: K = 0
Output: 5
Explanation: 0!, 1!, 2!, 3!, and 4! end with K = 0 zeroes.

Example 2:
Input: K = 5
Output: 0
Explanation: There is no x such that x! ends in K = 5 zeroes.

Note:

  • K will be an integer in the range [0, 10^9].

解题思路:

参考grandyang大神的解法:思路的关键在于末尾0其实是由2和5相乘得到的,而阶乘中2的数量远大于5的数量,所以10的个数取决于5的个数。但是像25增加了2个5,125增加了3个5;

另一个规律在于我们知道20,21,22,23,24,这五个数的阶乘数末尾零的个数其实是相同的,都是有4个,因为它们包含的5的个数相同。而19,18,17,16,15,这五个数末尾零个数相同,均为3。那么我们其实可以发现,每五个数,必会至少多出1个5,有可能更多。所以阶乘末尾零个数均为K个的x值,只有两种情况,要么是5,要么是0。

知道了如何快速求一个给定的数字阶乘末尾零的个数,那么我们只要找到了一个这样的数,其阶乘末尾零的个数等于K的话,那么就说明总共有5个这样的数,返回5,反之,如果找不到这样的数字,就返回0。那么像这种选一个candidate数字,再进行验证的操作,用二分搜索法就很好。我们首先要确定二分搜索法的范围,左边界很好确定,为0就行了,关键是来确定右边界,我们来分析一下,一个数字的阶乘末尾零个数为K,那么这个数字能有多大,就拿前面举的例子来说吧,末尾有4个0的最大数字是24,有六个0的最大是29,那么我们发现它们都不会超过5*(K+1)这个范围,所以这就是我们的右边界,注意右边界可能会超过整型数范围,所以要用长整型来表示。

class Solution {
public:
    int preimageSizeFZF(int K) 
    {
        long right = 5 * (long)(K + 1) , left = 0 ; //(k + 1)是int型 , *5也是int型再转换为long型,需要先将k变为long型,不然会溢出
        
        while(left < right)
        {
            long mid = left + (right - left) / 2 ;
            long cntz = cntofzero(mid) ;
            if(cntz < K) left = mid + 1 ;
            else if(cntz > K) right = mid ;
            else return 5 ;
        }
        
        return 0 ;
    }
    
    long cntofzero(long num)
    {
        long res = 0 ;
        while(num >= 5)
        {
            res += num / 5 ;
            num /= 5 ;
        }
        return res ;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值