"Coding Interview Guide" -- 阶乘

题目

  给定一个非负整数N,返回N!结果的末尾为0的数量

  例如,3! = 6,结果末尾没有0,则返回值为0;5!=120,结果的末尾有1个0,所以返回值为1; 1000000000!,结果的末尾有249999998个0,返回249999998

分析

  N! = N*(N-1)*(N-2)*...*2*1

  可能最直接的方法是直接算出N的阶乘的值,但是阶乘的结果通常非常大,当N=13时,就会发生溢出,所以直接计算阶乘值的方法不合适。

  考虑在什么情况下会产生0,1*0 = 0(0! = 1,1! = 1),2*5 = 10,4*5 = 2*(2*5) = 20,...,4*25  = (2*5)*(2*5) = 100 ,...,由此可见,N中具有因子2和5的时候就会产生0,有多少对2和5就会产生多少个0,而N中因子2的个数始终是不少于5的个数,所以,只需要统计N的阶乘中具有多少个因子5,就能知道N的阶乘结果的末尾有多少个0 

  那么该如何求N的阶乘中有多少个因子5呢,有两个方法:

  1、N的阶乘等于1~N这个序列的乘积,1~N中有的数含有因子5,有的数不含。计算1~N中所有含有因子5的数总共含有有多少个因子5,结果即为0的个数

 1 public int zeroNum(int num)
 2 {
 3     if(num <= 0) { return 0; }
 4 
 5     int res = 0;
 6         int cur;
 7     for(int i = 5; i <= num; i = i + 5)  //只需计算含有因子5的数所包含的因子5的具体个数
 8     {
 9         cur = i;
10         while(cur % 5 == 0)
11         {
12             res++;
13             cur /= 5;
14         }
15     }
16     return res;
17 }

  对代码中的每一个数i来说,计算其所含有的因子5的个数的时间复杂度是log(i)(以5为底),i=N时为log(N),一共有N个数,所以时间复杂度为O(NlogN)

  2、对于N!,它由1~N的乘积得到,即N!的因子为1,2,3,4,5,6,7,8,9,10...,15...,20...,25...,30...,35...,40...,45...,50...,55...,60...,

65...,70...,75...,80...,85...,90...,95...,100...,105...,110...,115...,120...,125...,130...

    观察5,10,15,20,25,30,35...,100,105,110,115,120,125,130等发现每5个含有0个因子5的数组成一组,第5个数就含有1个因子5;再观察25,50,75,100,125等发现每5个含有1个因子5的数组成一组,该组的第5个数就含有2个因子5;再观察125,250,375等发现每5个含有2个因子5的数组成一组,该组的第5个数就含有3个因子5;以此类推,每5个含有i个因子5的数组成一组,该组的第5个数就含有(i+1)个因子5...(注意上面说的是含有,是>=的意思,而不是只含有)

   所以,N!的结果中0的个数 = N/5 + N/(5^2) + N/(5^3) + ... + N/(5^i)(i一直增长,直到(5^i) > N)  (其中N/5表示每5个数就会有1个因子5;N/(5^2)表示每5^2个数就会有1个因子5,本来按照上面的分析是有2个的,但因为其中的一个因子5已经在N/5中计算过了,所以此处不必重复计算,N/(5^3)表示每5^3个数就会有1个因子5,本来应该有3个的,但是其中的2个已经在N/5和N/(5^2)中计算过...)

 1 public int zeroNum(int num)
 2 {
 3     if(num <= 0) { return 0; }
 4 
 5     int res = 0;
 6         while(num != 0)         // N/5 + N/(5^2) + N/(5^3) + ... + N/(5^i),直到(5^i) > N
 7     {
 8         num /= 5;
 9                 res += num;
10     }
11     return res;
12 }        

  方法2的时间复杂度为O(logN)(以5为底)  

来源:左程云老师《程序员代码面试指南》

猜你喜欢

转载自www.cnblogs.com/latup/p/10873058.html