1. 程式人生 > 其它 >【數學】力扣172:階乘後的零

【數學】力扣172:階乘後的零

給定一個整數 n ,返回 n! 結果中尾隨零的數量。
提示 n! = n * (n - 1) * (n - 2) * ... * 3 * 2 * 1
示例:

輸入:n = 3
輸出:0
解釋:3! = 6 ,不含尾隨 0

一個數學結論題。

每個尾部的 0 由 2 × 5 = 10 而來,那麼可以把階乘的每一個元素拆成質數相乘,統計有多少個 2 和 5。顯然,質因子 2 的數量遠多於質因子 5 的數量,因此題目可以轉化為階乘裡有多少個質因子 5

class Solution:
    def trailingZeroes(self, n: int) -> int:
        # n 為 0 是一種特殊情況
        if n == 0:
            return 0
        count = 0
        for num in range(1, n + 1):
            while num % 5 == 0:
                num //= 5
                count += 1
        return count

時間複雜度:O(n)。
空間複雜度:O(1)。

第一個自己寫的題!!!之前做過的行測題裡有類似選擇題所以知道思路。第一次沒有通過是while寫成了if,導致 25 這種含有多個 5 的數字只計入了一次。

參考官方解答,思路可以擴充套件一些,從num == 5開始計算,且每次增量5,因為n∈[0, 4]時count一定為0,而其他數不是5的倍數,沒有必要考慮,如果n很大就可以節省很多時間。

class Solution:
    def trailingZeroes(self, n: int) -> int:
        count = 0
        for num in range(5, n + 1, 5):
            while num % 5 == 0:
                num /= 5
                count += 1
        return count

方法2:數學優化
一系列推導之後發現count其實就是
因此可以通過不斷將 n 除以 5,並累加每次除後的 n,來得到答案。

class Solution:
    def trailingZeroes(self, n: int) -> int:
        ans = 0
        while n: # n > 0 時
            n //= 5
            ans += n
        return ans

作者:LeetCode-Solution
連結:https://leetcode-cn.com/problems/factorial-trailing-zeroes/solution/jie-cheng-hou-de-ling-by-leetcode-soluti-1egk/

時間複雜度:O(logn)。
空間複雜度:O(1)。

一行程式碼:

class Solution:
    def trailingZeroes(self, n: int) -> int:
        return 0 if n == 0 else n // 5 + self.trailingZeroes(n // 5)

在C++中:

int trailingZeroes(int n) {
    return n == 0? 0: n / 5 + trailingZeroes(n / 5);
}