- 題目描述
首先分析下n的階乘的規律:
- 題目分析
階乘 | 結果 |
1! | 1 |
2!=1*2 | 2 |
3!=1*2*3 | 6 |
4!=1*2*3*4 | 24 |
5!=1*2*3*4*5 | 120 (1個0) |
6!=1*2*3*4*5*6 | 720 (1個0) |
7!=1*2*3*4*5*6*7 | 5040 (1個0) |
8!=1*2*3*4*5*6**7*8 | 40320 (1個0) |
9!=1*2*3*4*5*6*7*8*9 | 362880 (1個0) |
10!=1*2*3*4*5*6*7*8*9*10 | 3628800 (2個0) |
11!=1*2*3*4*5*6*7*8*9*10*11 | 39916800 (2個0) |
.............. | ............ (2個0) |
15! = 1*2*3*4*5*6*7*8*9*10*11*12*13*14*15 | 1307674368000 (3個0) |
............ | ............ |
20!=1*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*19*20 | (4個0) |
以此類推 | 依此類推 |
故可發現規律:
(1)對於 1、2、3、4、5、6、7、8、9、10、11、12、13、............(&&&&)
可知上述數列,每個隔5個數的階乘後的結果,尾部零的個數會增加一個,即在
5.....10......15......20......25.......30....35......40.......45.......50......55......60......65......70......75.....80.......85.......90......100.........(*****)
這些數字均滿足 5*k 的數字。則在階乘數n之前,利用公式:數量 n1 = n/5,則可知在階乘數n之前,有n1個上述類型的數字。
例如: n = 56
則在56之前應該是5,10,15,20,25,30,35,40,45,50,55,
共56/5=11個數滿足上述數字特徵要求。
(2)將(****)處的特徵數字可以再進行規律尋找,可以化成
即爲: 5*(1、2、3、4、5、6、7、8、................)
此處可以提一個5出來,說明對應的每個階乘尾部至少都可達到有一個0;
括號中的數字1、2、3、4、5、6、7、8、..............又滿足(1)中的分析過程,對於(&&&&)中的原始數據,可以再次提出5的數字有:
........、25、.......、50、........、75、..........、100、..........、125、...........、150、..........、175、........
即爲:5*5*(1、2、3、4、5、6、7、8、....................)
此處可以提兩個5出來,說明對應的每個階乘尾部至少都可達到有兩個0;
括號中的數字1、2、3、4、5、6、7、8、..............又滿足(1)中的分析過程,對於(&&&&)中的原始數據,可以再次提出5的數字有:
......、125、........、250、.......、375、........、500、.......、625、........、750、..........
即爲:5*5*5*(1、2、3、4、5、6、7、8、................)
此處可以提三個5出來,說明對應的每個階乘尾部至少都可達到有三個0;
依次類推:
故可設計程序如下:
//迭代版本
class Solution {
public:
/*
* @param n: A long integer
* @return: An integer, denote the number of trailing zeros in n!
*/
long long trailingZeros(long long n) {
// write your code here, try to do it without arithmetic operators.
long long num = 0;
while(n)
{
num += n / 5; //將符號左邊的值與右邊值相加再賦值給左邊
n = n / 5;
}
return num;
}
};
代碼分析:
- 先定義0的個數計數變量num,賦初始值爲0,使用while循環語句,若滿足繼續,不滿足跳出,輸出計數值num。
例1:計算 4! 中尾數0的個數 4!=24
n=4,進入while循環,執行第一條語句:4 / 5 = 0,故 num = 0 + 4 / 5 =0+0=0 ;執行第二條語句:n = 4 /5 =0
故調出循環,輸出num=0.階乘尾部沒有0.
例2:計算14!中尾數0個數 14!=87178291200
n=14,進入while循環,執行第一條語句:14 / 5 = 2,故 num = 0 + 14 / 5 =0+2=2;執行第二條語句:n = 14 /5 =2;
繼續執行while循環,執行第一條語句:2/ 5 = 0,故 num = 0 + 2/ 5 =0+0=0;執行第二條語句:n = 2/5 =0;故調出循環,輸出num=2。階乘尾部有兩個0.
- 時間複雜度分析
題目要求我們時間複雜度爲O(logN),在算法中,每次循環均有除以5的操作,故每次循環數據量縮減爲原來的1/5,所以可以推出滿足時間複雜度。