zoukankan      html  css  js  c++  java
  • "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 = 0;
     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为底)  

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

  • 相关阅读:
    node.js系列:(调试工具)node-inspector调试Node.js应用
    NodeJs系列一:神奇的nodejs
    [原创] JavaScript实现简单的颜色类标签云
    jquery实现图片上传前本地预览
    前端制作入门知识
    解决pycharm中加载本地网页,弹出“requested without authorization”提示框不能加载网页的问题
    Mac中的Python安装selenium,结合chrom及chromdriver使用
    面试题(一)
    Python脚本之——API自动化框架总结
    红日ATT&CK红队评估实战靶场1
  • 原文地址:https://www.cnblogs.com/OoycyoO/p/10873058.html
Copyright © 2011-2022 走看看