问题:
求有多少个数的阶乘结果,末尾含有K个0的。
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].
解法:Factorial(阶乘),Binary Search(二分查找)
根据172. Factorial Trailing Zeroes
已经得到,如何求给定数n的阶乘中末尾含有多少个0。
1 long FactorialZeros(long n) {//count n! zero nums 2 long res = 0; 3 for(long d=n; d/5>0; d=d/5) { 4 res+=d/5; 5 } 6 return res; 7 }
那我们要求的则是,在所有数的阶乘中,
找 FactorialZeros(x)==K 的 x 共有多少个。
分析可知,随着 x 的增大,x! 中所含有5的因子也会变多,末尾0的数量也会增加。
是一个递增函数。
因此,我们可以使用二分查找,从0~LONG_MAX的所有数中,
找到满足 FactorialZeros(x)==K 的x的上限和下限,
二者之差,即为所求。
二分查找
参考:69. Sqrt(x)
1 int binary_search(int l, int r) { 2 // range: [l,r) 3 while(l<r) {// ★ 4 int m = l+(r-l)/2; 5 if(g(m)) {// ★ find first val which meet the condition g(m) 6 r = m; // ★ 7 } else { 8 l = m+1; 9 } 10 } 11 return l; // ★ 12 }
代码参考:
1 class Solution { 2 public: 3 long FactorialZeros(long n) {//count n! zero nums 4 long res = 0; 5 for(long d=n; d/5>0; d=d/5) { 6 res+=d/5; 7 } 8 return res; 9 } 10 long findUpperBound(int k) { 11 long l = 0, r = LONG_MAX; 12 while(l<r) { 13 long m = l+(r-l)/2; 14 if(FactorialZeros(m)>k) {// find first val which FactorialZeros(m)>k 15 r = m; 16 } else { 17 l = m+1; 18 } 19 } 20 return l; 21 } 22 long findLowerBound(int k) { 23 long l = 0, r = LONG_MAX; 24 while(l<r) { 25 long m = l+(r-l)/2; 26 if(FactorialZeros(m)>=k) {// find first val which FactorialZeros(m)>=k 27 r = m; 28 } else { 29 l = m+1; 30 } 31 } 32 return l; 33 } 34 int preimageSizeFZF(int K) { 35 return findUpperBound(K)-findLowerBound(K); 36 } 37 38 };