計算n階乘的末尾有幾個0

一、問題描述:在lintcode上有這麼一個問題,如下圖所示。設計一個算法,計算出n階乘中尾部零的個數。

二、嘗試

(1)相信很多人看到這個問題的第一個想法就是,先計算n階乘的結果,然後對10進行求餘判斷,而被10整除的次數就是尾部零的個數。代碼如下:

long long trailingZeros(long long n) {
        // write your code here, try to do it without arithmetic operators.
        //計算n階乘
        int s=1;
        for(int i=1;i<=n;i++)
        {
            s=s*i;
        }
        //對結果進行判斷
        int num = 0;
        //對10進行求餘
        while(s%10==0)
        {
            num++;
            s = s/10;
        }
        return num;
    }

看結果,說容易陷入死循環。爲什麼會陷入死循環呢?n纔是105哎,105!等於多少?用了一個在線階乘計算器計算髮現結果很大1.0813967582402912e+168。而int是32位,數據早已溢出,所以,用於存放階乘結果的s要改成長整型long long int。

(2)再次嘗試,發現依然運行超時。看來計算n階乘佔用的空間和時間都比較長。

(3)當我們嘗試從1到n逐次計算n階乘時,會發現一個規律,遇見能被5整除的數時,尾部0就可+1;而尾部的0一共有多少個,就要看這個數包含多少個5的因子。比如1到4的階乘結果分別爲1、2、6、24,5到9的階乘結果是120、720、5040、40320、362880,10到14的結果分別是3628800、39916800、479001600、6227020800、87178291200,然後15!=1307674368000。也就是5有一個0,10有2個0,15有3個0,20有4個0,25有6個0,30有7個0等等,代碼如下

long long trailingZeros(long long n) {
        // write your code here, try to do it without arithmetic operators.
        //計算n階乘
        long long num = 0;
        long long temp=n;
        while(temp)
        {
            temp /= 5;
            num += temp;
        }
        
        return num;
    }

 結果

 

 值得注意的一件事就是,其中數據類型的定義,要是long long類型的,這一點題目在定義的時候函數結果上也有提示。

在線計算階乘的地址http://www.99cankao.com/statistics/factorial-calculator.php

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