【lintcode】2.尾部的零(c/c++/python解法)

題目

設計一個算法,計算出n階乘中尾部零的個數
樣例
樣例 1:

輸入: 11
輸出: 2
樣例解釋: 
11! = 39916800, 結尾的02個。

樣例 2:

輸入:  5
輸出: 1	
樣例解釋: 
5! = 120, 結尾的01個。

挑戰
O(logN)的時間複雜度

1.c++/c解法

第一次

想法是通過向十取餘來計算零的個數

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) 
    {
       
        int t=0,s=1;
        for(int i = 1 ;i <= n ; i++)
        {
            s *= i;
        }
        while(s%10 == 0)
        {
            t++;
            s /= 10;
        }
        return t;
    }
};

第一次測試數據通過了,但是提交失敗。測試數據達到12階乘以上全部失敗,而且運行時間超時。打算顛倒數字重頭開始計算零的數字

long long trailingZeros(long long n)
    {

        int t=0,s=1;
        int r[150000];
        for(int i = 1 ;i <= n ; i++)
        {
            s *= i;
        }
        while(s != 0)
        {
            r[t] = s % 10;
            t++;
            s /= 10;
        }
        int len = 0;
        for(;r[len]==0;len++)
        {
            if(r[len]!=0)
                break;
        }
        return len;
    }

再一次失敗後覺得是數組長度問題,修改數組長度後還是錯誤。於是覺得是算法問題,不能用數組存放。於是直接每顛倒一位數字便進行判斷:

   long long trailingZeros(long long n)
    {

        int t=0,s=1;
        for(int i = 1 ;i <= n ; i++)
        {
            s *= i;
        }
        int len=0;
        while(s != 0)
        {
            int r;
            r = s % 10;
            if(r==0)
                {
                    len++;
                }
            else break;
            t++;
            s /= 10;
        }
       
        return len;
    }

發現這樣的方法還是錯誤,發現是存放階乘結果的s長度不夠。於是修改爲long long int 定義s。結果還是失敗,於是開始反思算法。

修改版算法

可以將每個數拆分成其素因子的乘積,可以發現,0是由2*5產生的,而5的數量一定小於2的數量,因此5的個數決定了結尾0的個數。
只要計算n的階乘中,5這個素因子出現多少次即可。

class Solution {
public:
    // param n : description of n
    // return: description of return 
    long long trailingZeros(long long n) {
        long long sum = 0;
        while (n != 0) {
            sum += n / 5;
            n /= 5;
        }
        return sum;
    }
};

或者是:

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) {
        // write your code here, try to do it without arithmetic operators.
        long long numFactor5 = 0;
        
        while (n >= 5)
        {
            n = n / 5;
            numFactor5 += n;
        }

        return numFactor5;
    }
};

python解法

可以將每個數拆分成其素因子的乘積,可以發現,0是由2*5產生的,而5的數量一定小於2的數量,因此5的個數決定了結尾0的個數。
只要計算n的階乘中,5這個素因子出現多少次即可。

class Solution:
    # @param n a integer
    # @return ans a integer
    def trailingZeros(self, n):
        sum = 0
        while n != 0:
            n /= 5#這裏可以替換爲n //= 5(//代表抹除小數部分取整數)
            sum+= n
        return sum

說實話,這種方法不太會。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章