1. 程式人生 > >階乘尾部的0(解法思路)

階乘尾部的0(解法思路)

return long 編程題 兩個 body with rail 階乘的計算 temp

昨天看到一個編程題,以為很簡單,結果還費了一番周折才做出來。

題目:設計一個算法,計算出n階乘中尾部零的個數

樣例

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

思路: 最無腦的辦法就是直接求出階乘的值,然後統計尾部的0:

 1 class Solution {
 2 public:
 3     /*
 4      * @param n: A long integer
 5      * @return: An integer, denote the number of trailing zeros in n!
 6      */
 7     long long trailingZeros(long
long n) { 8 if(n==0||n==1) 9 {return 0;} 10 11 long long result=1; 12 // write your code here, try to do it without arithmetic operators. 13 for(long long i=1;i<=n;i++) 14 { 15 result = result*i; 16 } 17 int count=0
; 18 while(result%10==0) 19 { 20 count++; 21 result = result/10; 22 } 23 return count; 24 } 25 };

這種方法簡單粗暴,但是如果給定n的值很大的話,求階乘的計算量非常大。

下面就有了第二種思路,在乘法計算裏,只要乘以一個10或者10的個位數倍數,結果的後面就會增加一個0。

因為n的階乘中一定會有n/2個偶數,所以我們只需要考慮有多少個5的倍數,結果的末尾就會增加多少個0。

這裏還要考慮到一種情況就是,如果被乘數是5的n次方的倍數話,就結果的末尾增加n個0,例如25可以表示成5*5,一定可以找到一個4的倍數和他相乘使得結果末尾增加兩個0;

那麽到這裏,思路就可以確認為:判斷有多少個被乘數是5的倍數,如果是5的倍數的話,再判斷這個數是不是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) {
        if(n==0||n==1)
        {return 0;}
        
        int count=0;
        long long temp = 0;
        // write your code here, try to do it without arithmetic operators.
        for(long long i=1;i<=n;i++)
        {
            temp = i;
            while(temp%5==0)
            {
                count++;
                temp = temp/5;
            }

        }

        return count;
    }
};

這樣雖然優化了很多,但是時間復雜度是O(N/5)~=O(N),還是沒有達到O(logN)的要求,

最開始想到我要看從1~n裏有多少個5的倍數,只需要直接用n除以5就可以知道結果了,但是5的倍數裏面還包含了25、125······這些5的多次冪。

如果遇到這些數的話,結果就不是加1而是加2加3····;

但是如果換個思路,我們在統計5的倍數的時候,已經就吧25,125····這些數統計進去了,25的倍數就是比5的倍數能多提供一個0;125的倍數就是能在5的倍數和25的倍數的基礎上再多提供一個0····

依此類推,那我們需要求的結果其實就是

n/5 + n/25 + n/125 + n/625······

代碼實現:

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) {
        long long count=0;
        long long a = n/5;
        while(a>0)
        {
            count=count+a;
            a=a/5;
        }

        return count;
    }
};

階乘尾部的0(解法思路)