每日一題之 經典面試題 N!末尾有多少個0
阿新 • • 發佈:2018-12-09
問題:N的階乘(N!)中的末尾有多少個0? 例如: N = 5,N! = 120.末尾有1個0. N = 10,N! = 3628800.末尾有2個0。
分析:看到這個問題,有人可能第一反應是先求出N!,然後再根據求出的結果,最後得出N!的末尾有多少個0。但是轉念一想,會不會溢位。
其實,從”哪些數相乘可以得到10”這個角度,問題就變得比較的簡單了。 首先考慮,如果N的階乘為K和10的M次方的乘積,那麼N!末尾就有M個0。 N的階乘可以分解為: 2的X次方,3的Y次方,5的次Z方…..的一系列質因子相乘。由於10 = 2 * 5,所以M只能和X和Z有關,每一對2和5相乘就可以得到一個10,於是M = MIN(X,Z),因為是階乘,所以2的次方X大於5的次方Z,因為被2整除的頻率比被5整除的頻率高的多。所以可以把公式簡化為M=Z.
由上面的分析可以看出,只要計算出Z的值,就可以得到N!末尾0的個數
方法一 要計算Z,最直接的方法就是求出N的階乘的所有因式(1,2,3,…,N)分解中5的指數。然後求和
int fun1(int n)
{
int num = 0;
int i,j;
for (i = 5;i <= n;i += 5)
{
j = i;
while (j % 5 == 0)
{
num++;
j /= 5;
}
}
return num;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
方法二:
Z = N/5 + N /(5*5) + N/(5*5*5)…..直到N/(5的K次方)等於0
公式中 N/5表示不大於N的數中能被5整除的數貢獻一個5,N/(5*5)表示不大於N的數中能被25整除的數再貢獻一個5…….
int fun2(int n)
{
int num = 0;
while(n)
{
num += n / 5;
n = n / 5;
}
return num;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12