LintCode 第二題 尾部的零

2021-08-18 10:50:01 字數 1731 閱讀 7972

描述: 

設計乙個演算法,計算出n階乘中尾部零的個數

樣例: 

11! = 39916800,因此應該返回 2

假如你把1 × 2 ×3× 4 ×……×n中每乙個因數分解質因數,結果就像: 1 × 2 × 3 × (2 × 2) × 5 × (2 × 3) × 7 × (2 × 2 ×2) ×…… 10進製數結尾的每乙個0都表示有乙個因數10存在——任何進製都一樣,對於乙個m進製的數,讓結尾多乙個0就等價於乘以m。10可以分解為2 × 5——因此只有質數2和5相乘能產生0,別的任何兩個質數相乘都不能產生0,而且2,5相乘只產生乙個0。 所以,分解後的整個因數式中有多少對(2, 5),結果中就有多少個0,而分解的結果中,2的個數顯然是多於5的,因此,有多少個5,就有多少個(2, 5)對。 所以,討論1000的階乘結尾有幾個0的問題,就被轉換成了1到1000所有這些數的質因數分解式有多少個5的問題。

假設有序列1、2、3、4、5、6、7、8、9、10、11、…

分析上面的數列可知,每5個數中會出現乙個可以產生結果中0的數字。把這些數字抽取出來是:

…、5、…、10、…、15、…、20、…、25、…

這些數字其實是都能滿足5*k的數字,是5的倍數。統計一下他們的數量:n1=n/5。比如如果是101,則101之前應該是5,10,15,20,…,95,100共101/5=20個數字滿足要求。

整除操作滿足上面的數量統計要求。

將1中的這些數碼化成5*(1、2、3、4、5、…)的形式,內部的1、2、3、4、5、…又滿足上面的分析:每5個數字有乙個是5的倍數。抽取為:

…、25、…、50、…、75、…、100、…、125、…

而這些數字都是25的倍數(5的2次冪的倍數),自然也都滿足5*k的要求。 

這些數字是25、50、75、100、125、…=5*(5、10、15、20、25、…)=5*5*(1、2、3、4、5、…),內部的1、2、3、4、5、…又滿足上面的分析,因此後續的操作重複上述步驟即可。

統計一下第二次中滿足條件的數字數量:n2=n/5/5,101/25=(101/5)/5=4。

因為25、50、75、100、125、…它們都滿足相乘後產生至少兩個0,在第一次5*k分析中已經統計過一次。對於n=101,是20。因此此處的5*5*k只要統計一次4即可,不需要根據25是5的二次冪統計兩次。

後面的125,250,…等乘積為1000的可以為結果貢獻3個0的數字,只要在5*5*k的基礎上再統計一次n3=((n/5)/5)/5即可。

核心點:尾部的零有5的個數決定,單5(因式分解後有1個5)與某偶數相乘有單0,多5(因式分解後有多個5)與某偶數相乘有多個0。

[python]view plain

copy

class

solution:  

"""@param: n: an integer

@return: an integer, denote the number of trailing zeros in n!

"""def

trailingzeros(

self

, n):  

# write your code here, try to do it without arithmetic operators.

sum = 0

while

n > 

0:  

sum += n /5

n /= 5

return

sum  

lintcode第二題 計算n階乘中尾部零的個數

設計乙個演算法,計算出n階乘中尾部零的個數 樣例11 39916800,因此應該返回 2 挑戰o logn 的時間複雜度 先說結論,此問題大致有三種思路 第一種算出結果,然後檢視末尾的0的個數,效果非常差 第二種,加法操作,從5開始,每次進5,然後判斷,效果達不到o logn 第三種,每次除5,多次...

LintCode 尾部的零

尾部的零 設計乙個演算法,計算出n階乘中尾部零的個數 樣例 11 39916800,因此應該返回 2 挑戰 o logn 的時間複雜度 solutioin factorials and trailing zeroes 1.計算 23 有多少個尾0 23 1 2 3 4 5 6 7 8 9 10 11...

lintcode尾部的零

設計乙個演算法,計算出n階乘中尾部零的個數 class solution param n an integer return an integer,denote the number of trailing zeros in n deftrailingzeros self,n write your ...