【刷算法】LeetCode- 阶乘后的零

原题地址:LeetCode中国-172

题目描述

给定一个整数 n,返回 n! 结果尾数中零的数量。

示例 1:

输入: 3
输出: 0
解释: 3! = 6, 尾数中没有零。
示例 2:

输入: 5
输出: 1
解释: 5! = 120, 尾数中有 1 个零.

说明: 你算法的时间复杂度应为 O(log n) 。

分析

首先暴力破解法就是直接把最终的结果求出来然后看末尾有几个0,但是这样做的时间复杂度肯定是太大了。

然后考虑到末尾的0是怎么形成的,首先10=2*5,20=2*2*5,30=3*2*5 … 100=10*2*5

所以,问题的关键是看阶乘里面2和5的数量,但是因为显然2出现的数量大于5出现的数量,拿5的阶乘来举例子:

5!= (1) * (2) * (3) * (2*2) * (5)

出现了3个2、1个5,但是末尾只有1个0,所以阶乘末尾0的个数就是阶乘式中5的个数。但是如解法1的代码所示,时间复杂度还是太高。

继续考虑,对于50!,我们可以写成:

5 … 2*5 … 3*5 … 4*5 … 5*5 … 6*5 … 7*5 … 8*5 … 9*5 … 10 * 5

可以看出来从5到10*5一共有10个5,但是对于10来说,从1到10还有2个5,所以50!的结果末尾有12个0

解法1(不符合要求的时间复杂度)

var trailingZeroes = function(n) {
  var count  = 0;
    
  for(var i = 1;i <= n;i++){
    var temp = i;
    while(temp%5 === 0){
      count++;
      temp /= 5;
    }
  }
  
  return count;
};

上面这个解法的时间复杂度是n*(logn),不符合题意

解法2

var trailingZeroes = function(n) {
  var count  = 0;
    
  while(n) {
    count += divide(n,5);
    n = divide(n,5);
  }
  
  return count;
};
  
function divide(n, m) {
  return Math.floor(n/m);
}
    原文作者:亚古
    原文地址: https://segmentfault.com/a/1190000015891874
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞