算法学习之旅
問題:設(shè)計(jì)一個(gè)算法,計(jì)算出n階乘中尾部零的個(gè)數(shù)
例如: 11! = 39916800,因此應(yīng)該返回 2
挑戰(zhàn):O(logN)的時(shí)間復(fù)雜度
想法1:
找出1–n中每個(gè)數(shù)字能夠被5或者10整除的次數(shù),加在一起就是答案。但是時(shí)間復(fù)雜度是O(N2).代碼如下:`public static long trailingZeros(long n) {
// write your code here
long five=0;
long count=0;
for(long i=1;i<=n;i++){
if(i%10==0){
long j=i;
while(j>1 && j%10==0){
j/=10;
count++;
}
if(j%5==0){
while(j>1 && j%5==0){
j/=5;
count++;
}
}
}else if(i%5==0){
long k=i;
while(k>1 && k%5==0){
k/=5;
count++;
}
}
想法2.統(tǒng)計(jì)1—n 能被5整除的次數(shù),累加求和,代碼類似上邊
想法3:對想法2進(jìn)行優(yōu)化,只對1—n之中能夠被5整除的數(shù)進(jìn)行統(tǒng)計(jì)。代碼如下:
public static long trailingZeros(long n) {
// write your code here
long five=0;
long count=0;
if(n<5){
return 0;
}else if(n==5){
return 1;
}
for(long i=5;i<=n;i+=5){
if(i%5==0){
long j=i;
while(j>0 && j%5==0){
j/=5;
count++;
}
}
}
return count;
}
《編程之美》上的想法3:
公式:Z = [N/5] +[N/52] +[N/53] + …(不用擔(dān)心這會是一個(gè)無窮的運(yùn)算,因?yàn)榭偞嬖谝粋€(gè)K,使得5K > N,[N/5K]=0。)
5的倍數(shù)貢獻(xiàn)一個(gè)5,5的平方貢獻(xiàn)兩個(gè)5~~~.
代碼如下:
int num = 0, i;
for(i=5; i<=n; i*=5)
{
num += n/i;
}
return num;
又簡潔,執(zhí)行效率又高,與君共勉之。
總結(jié)
- 上一篇: 北大未名二号高性能计算集群暨华为全球样板
- 下一篇: lintcode 有效的括号序列