题解 | #阶乘末尾0的数量#

阶乘末尾0的数量

http://www.nowcoder.com/practice/aa03dff18376454c9d2e359163bf44b8

题目

描述

给定一个非负整数 NN,返回 N!N! 结果的末尾为 00 的数量。
N!N! 是指自然数 NN 的阶乘,即:

方法一

思路

  • 题目要求计算阶乘末尾0的数量,最直接的方法就是通过计算n!,得出其值,然后在逐个的找出末尾的0,得出末尾0的数量;
  • 考虑到N的范围比较大,使用long会溢出,所以采用Java中BigDecimal来进行阶乘的运算;
  • 得出阶乘的结果后,再将数值转换成字符串,从尾部开始遍历,找出末尾所有的零。
  • 代码如下:
    import java.util.*;
    import java.math.BigDecimal;
    public class Solution {
      /**
       * the number of 0
       * @param n long长整型 the number
       * @return long长整型
       */
      public long thenumberof0 (long n) {
          // 使用BigDecimal来存储乘积
          BigDecimal multi = new BigDecimal(String.valueOf(1));
          // 实现阶乘运算
          while(n > 1){
              BigDecimal bb = new BigDecimal(String.valueOf(n));  
              multi = multi.multiply(bb);
              --n;
          }
          // 找出末尾零的的个数
          int count = 0;
          String str = String.valueOf(multi);
          for (int i = str.length()-1;i >= 0;--i){
              if (str.charAt(i) != '0'){
                  break;
              }
              ++count;
          }
          return count;
      }
    }
  • 时间复杂度:,计算阶乘需要,BigDecimal乘法的时间复杂度为,分别为两个数的长度;
  • 空间复杂度:,由于最后会将阶乘值转换成字符串,所以需要阶乘值的长度的空间,关于阶乘值存在如下计算公式(斯特林公式):;而对于一个十进制数X的长度则存在如下计算公式:

方法二

思路

  • 由于N的范围比较大,所以采用方法一可能会导致程序运行超时,无法啊完美解决问题,需要考虑降低时间复杂度,从而提高程序运行速度;
    图片说明
    图片说明
    图片说明
    图片说明

  • 观察10以内的数字的互乘,可以发现只有2 * 5 = 10会产生0,也就是说两个数相乘会产生0,则这两个数中必有因子5和2,且5的个数一定是小于2的个数的,所以要找出一个阶乘n!末尾0的数量,只需要找出从1~n这n个数中总共有多少个因子5;

  • 但是,从1遍历到n每个数看一下它能除多少次5是不行的。因为n的数据范围是1e18,遍历1e18个数运行时间过大。

  • 其实存在如下公式:5的数量count = n/5+n/25+……+n/5+……;

  • 那么这公式是什么意思呢?n/5即阶乘中所有至少含有一个因子5的个数,而n/25即阶乘中所有至少含有两个因子5的个数,由于在n/5中已经统计一次n/25了,所以只需要在加一次n/25即可,以此类推,从而得出n的阶乘中因子5的个数。

  • 故可以依据此公式进行计算末尾0的数量。

  • 代码如下:

    import java.util.*;
    import java.math.BigDecimal;
    public class Solution {
      /**
       * the number of 0
       * @param n long长整型 the number
       * @return long长整型
       */
      public long thenumberof0 (long n) {
    
          long count = 0;
          long base = 5;
          while(n >= base){
              count = count + n / base;
              base *= 5;
          }
          return count;
      }
    }
  • 时间复杂度:,从0~n遍历;

  • 空间复杂度:,常数级空间复杂度。

全部评论

相关推荐

11-15 17:19
湖南大学 Java
成果成果成果果:这是哪个公司的hr,这么离谱吗,我没见过用性别卡技术岗的,身边女性同学拿大厂offer的比比皆是
点赞 评论 收藏
分享
1 1 评论
分享
牛客网
牛客企业服务