2 尾部的零

2021-08-21 13:19:45 字數 2092 閱讀 3777

問題描述:設計乙個演算法,計算出n階乘中尾部零的個數。

樣例:11!

=3991680011!

=39916800

,因此應該返回 2。

解答(js實現):

const trailingzeros = function

(n)

return sum;

}

分析:思考乙個數尾部的零是怎麼得來的,乘以10對吧,所以n的階乘尾部有多少零就可以看成它有多少個10這個因子,而10又可分解為兩個質因數相乘 2×

5 2×5

。將 n!

n

!分解為質因數相乘的形式,大概是這樣: n!

=1×2

×3×(

2×2)

×5×(

2×3)

×7×(

2×2×

2)×(

3×3)

×(2×

5)..

. n!=

1×2×

3×(2

×2)×

5×(2

×3)×

7×(2

×2×2

)×(3

×3)×

(2×5

)...

顯然,2的個數會比5的個數多,所以有多少個5就會有多少個10。故而問題就轉化為尋找 n!

n

!的結果有多少個5這個因子。

那麼這個怎麼找呢?我們看一下上邊的等式,現在已經乘到10了,出現了2個5,想象一下繼續乘下去的情況,到15時會再出現乙個,到20時又會再出現乙個,到25時則會出現2個,繼續看下去,就會發現乙個規律:

(1) 每逢遇到5的倍數,就會出現乙個;

(2) 每逢遇到5的冪次方的倍數,就會出現5的冪次方的指數個,為了便於計算,我們把遇到5的冪次方的倍數時也算到5的倍數裡,這時遇到5的冪次方的倍數就會出現(5

的冪次方

的指數−

(5的冪

次方的指

數−1)

) (5的冪

次方的指

數−(5

的冪次方

的指數−

1)

)個,也就是1個。

這樣用文字來說會有點繞,我們不妨用代數式說明一下:

根據以上,我們不難得出乙個公式: su

m=n5

+n52

+n53

+n54

+⋅⋅⋅

s um

=n5+

n52+

n53+

n54+

··

·有了這個公式,問題就容易了,只需求出

log5

n log5⁡

n,取整,然後將其作為迴圈次數累加就行了。

js中有math.log()函式,返回乙個數的自然對數(loge, 即ln)。雖然沒有直接求

log5

n log5⁡

n的方法,但

log5n=

lnnln5

log5⁡n

=ln⁡n

ln⁡

5,所以n(包括n)以內5的冪次方的最大指數可求得:

var power = math.floor(math.log(n) / math.log(5));
至此,我們從1開始迴圈到power,每次迴圈都加上公式中對應迴圈次數的項,即可得到結果:

var sum = 0;

for (var i=1;i<=power;i++)

總結:由以上的計算方式可以看出,power就是 lnnln⁡

n,所以符合o(logn)的時間複雜度。在做這道題時,也找了不少資料,很多都提到求sum的那個公式,但是具體怎麼來的都沒有很清晰地寫思路,於是自己就試了試,期間也跑偏了幾次,還好最後自圓其說地歸納出來了,希望對看到的朋友有所幫助。

另外,還有一種思路也能按o(logn)的時間複雜度實現,這篇部落格對於另一種思路寫得很清晰,博主很用心,推薦一下 ^-^ 。

2 尾部的零

問題描述 設計乙個演算法,計算出n階乘中尾部零的個數 樣例11 39916800 因此應該返回 2.這個問題相信很多老鐵都已經遇到過了,很經典的乙個題目,還是那句老話,重要的是考慮的過程,是如何想到以5的個數來統計0的個數呢?又是如何想到除以25 除以125.的呢?這些事重點。首先n 中,哪些數字相...

2 尾部的零

描述 設計乙個演算法,計算出n階乘中尾部零的個數。樣例 11 39916800,因此應該返回 2 挑戰 o logn 的時間複雜度 分析 假如你把1 2 4 n中每乙個因數分解質因數,結果就像 1 2 3 2 2 5 2 3 7 2 2 2 10進製數結尾的每乙個0都表示有乙個因數10存在 任何進製...

2 尾部的零

剛看到這道題時沒多考慮,就是利用階乘算出結果然後轉為字元陣列,判斷零的個數 剛發現判斷的地方寫錯了 但是如果輸入的值非常大,超過了取值範圍,就會報錯,而且這道題的思路不是這樣的 我是個沒有腦子的人!思路 乘積中出現0一定是2和5的乘積具體思路就不寫了,別人都寫好了 public class seco...