【刷演算法】LeetCode- 階乘後的零

亞古發表於2018-08-05

原題地址:LeetCode中國-172

題目描述

給定一個整數 n,返回 n! 結果尾數中零的數量。

示例 1:

輸入: 3輸出: 0解釋: 3! = 6, 尾數中沒有零。示例 2:

輸入: 5輸出: 1解釋: 5! = 120, 尾數中有 1 個零.

說明: 你演算法的時間複雜度應為 O(log n) 。

分析

首先暴力破解法就是直接把最終的結果求出來然後看末尾有幾個0,但是這樣做的時間複雜度肯定是太大了。
然後考慮到末尾的0是怎麼形成的,首先10=2*5,20=2*2*5,30=3*2*5 … 100=10*2*5
所以,問題的關鍵是看階乘裡面2和5的數量,但是因為顯然2出現的數量大於5出現的數量,拿5的階乘來舉例子:

5!= (1) * (2) * (3) * (2*2) * (5)

出現了3個2、1個5,但是末尾只有1個0,所以階乘末尾0的個數就是階乘式中5的個數。但是如解法1的程式碼所示,時間複雜度還是太高。

繼續考慮,對於50!,我們可以寫成:

5 … 2*5 … 3*5 … 4*5 … 5*5 … 6*5 … 7*5 … 8*5 … 9*5 … 10 * 5

可以看出來從5到10*5一共有10個5,但是對於10來說,從1到10還有2個5,所以50!的結果末尾有12個0

解法1(不符合要求的時間複雜度)

var trailingZeroes = function(n) { 
var count = 0;
for(var i = 1;
i <
= n;
i++){
var temp = i;
while(temp%5 === 0){
count++;
temp /= 5;

}
} return count;

};
複製程式碼

上面這個解法的時間複雜度是n*(logn),不符合題意

解法2

var trailingZeroes = function(n) { 
var count = 0;
while(n) {
count += divide(n,5);
n = divide(n,5);

} return count;

};
function divide(n, m) {
return Math.floor(n/m);

}複製程式碼

來源:https://juejin.im/post/5b66a3baf265da0f664046f1

相關文章