leetcode172-Factorial Trailing Zeroes(求N!末尾有多少个0)

问题描述:

Given an integer n, return the number of trailing zeroes in n!.

给定一个整数N,那么阶乘N!末尾有多少个0呢? 例如N=10,N!=3628800,则N!的末尾有两个0.

问题求解:

求阶乘的末尾0的个数,其实就是求这个N!能有多少个乘数为10。

如果按照传统的方法,先计算出N!的结果再来看有多少个0,那就很不实际,结果很容易越界。而我们只要求N!中,10作为乘数的个数就可以了。利用10=2*5,只要求2*5的个数即可。

进行质因数分解:N! = (2^x) * (3^y) * (5^z) ……

2*5的个数= min(x, z)。再进一步考虑,发现,能被2整除的数出现的频率高于被5整除的数。即2*5 的个数 m= min(x, z) = z .

根据上面分析,只要计算出z的值就可以得到N!末尾有多少个0.

#include <iostream>

using namespace std;
/* 解法1: 计算i(i = 1,2,3..N)的因式分解中5的指数 */
int SumZero1(int N)
{
    int ret = 0;
    for(int i=1;i<=N;i++)
    {
        int j=i;
        while(j % 5 == 0)
        {
            ret++;
            j /= 5;
        }
    }
    return ret;
}
/* 解法2: z = [N/5] + [N/(5*5)] + [N/(5*5*5)]...
[N/5]为N中5的个数,[N/(5*5)]为[N/5]中5的个数 ...
Z为N!中含有5的总个数 */
int SumZero2(int N)
{
    int ret = 0;
    while(N)
    {
        ret += N / 5;
        N = N / 5;
    }
    return ret;
}
int main()
{
    int N=10;
    cout << SumZero1(N) << endl;
    cout << SumZero2(N) << endl;
    return 0;
}

扩展:

用十进制计算30!(30的阶乘),将结果转换成3进制进行表示的话,该进制下的结果末尾会有多少个0? 答案14

计算N!下三进制结果末尾有多少个0,其实就是计算三进制中的3被移位了多少次,就像二进制一样,每乘以2就向左移一位,末尾补0,因此这道题只要将N!因式分解成3^m*other,m就是答案。
技巧性的解法就是m=N/3+N/(3^2)+N/(3^3)….+N(3^k) (k<=N/3)。

你可能感兴趣的:(LeetCode,编程之美)