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) = 2
because 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 ;
}
};