793. Preimage Size of Factorial Zeroes Function

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].
 

Approach #1: Bianry Serach.

class Solution {
public:
    int preimageSizeFZF(int K) {
        return (int)(searchNum(K) - searchNum(K-1));
    }
    
private:
    long findNumOfZeros(long x) {
        long res = 0;
        for (; x > 0; x /= 5) {
            res += x / 5;
        }
        return res;
    }
    
    long searchNum(int x) {
        long l = 0, r = 5 * (x + 1);
        while (l <= r) {
            long m = l + (r - l) / 2;
            long count = findNumOfZeros(m);
            if (count > x) r = m - 1;
            else l = m + 1;
        }
        return r;
    }
};

Runtime: 0 ms, faster than 100.00% of C++ online submissions for Preimage Size of Factorial 

 

Analysis:

step1:

the number of zero with factorial's result equal to the number of 5 in factorial.

eg:

5! = 1 * 2 * 3 * 4 * 5 = 120

11! = 1 * 2 *...* 5 *... * 9 * 10 *...* 11 = 39916800

 

25! = 1 * 2 *...* 5 *... * 9 * 10 *...* 15 * ... * 20 * .... * 25  || in this case the number of 5 equal to 25 / 5 + 25 / 25 + 25 / 125

so wecan get the faction of findNumOfZeros();

    long findNumOfZeros(long x) {
        long res = 0;
        for (; x > 0; x /= 5) {
            res += x / 5;
        }
        return res;
    }

step 2:

we can use binary search to find the num1 (range with [0, 5*(K + 1)]) whose factorial with K zeros and num2 whose factorial with K - 1 zeros.

    long searchNum(int x) {
        long l = 0, r = 5 * (x + 1);
        while (l <= r) {
            long m = l + (r - l) / 2;
            long count = findNumOfZeros(m);
            if (count > x) r = m - 1;
            else l = m + 1;
        }
        return r;
    }

finally find the answer num1 - num2.

 

posted @ 2018-11-09 20:52  Veritas_des_Liberty  阅读(295)  评论(0编辑  收藏  举报