LeetCode探索(135):793-阶乘函数后 K 个零

195 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第32天,点击查看活动详情 >>

题目

f(x)x! 末尾是 0 的数量。回想一下 x! = 1 * 2 * 3 * ... * x,且 0! = 1

  • 例如, f(3) = 0 ,因为 3! = 6 的末尾没有 0 ;而 f(11) = 2 ,因为 11!= 39916800 末端有 2 个 0 。

给定 k,找出返回能满足 f(x) = k 的非负整数 x 的数量。

示例 1:

输入:k = 0
输出:5
解释:0!, 1!, 2!, 3!, 和 4! 均符合 k = 0 的条件。

示例 2:

输入:k = 5
输出:0
解释:没有匹配到这样的 x!,符合 k = 5 的条件。

示例 3:

输入: k = 3
输出: 5

提示:

  • 0 <= k <= 10^9

思考

本题难度简单。

首先是读懂题意。 定义f(x) 是 阶乘x! 末尾是 0 的数量,需要注意的是0! = 1 。给定 k,找出返回能满足 f(x) = k 的非负整数 x 的数量。

我们可以观察下不同数字的阶乘的末尾0的数量:

nn! 末尾0的数量 k
0~40
5~91
10~142
15~203
21~244
/5
25~296

当 k = 3 时,我们可知这样的数字有5个。当 k = 5 时,我们可知这样的数字有0个。

对于给出的任意数字 k,preimageSizeFZF(k)的结果是 5 或 0。

我们定义函数zeros(n)计算数字 n 的阶乘的末尾0的数量。比如 zeros(25) === 6。我们可以遍历数字 x,计算 zeros(x)的结果,判断是否存在 x 满足 zeros(x) === k,若存在 x 则答案为5,否则答案为0。

考虑到数字 k 可能很大,如果我们从 0 开始遍历 x 时会超时。因此,这里我们是从 k * 4 开始遍历,直至zeros(start) >= k为止。

解答

方法一:遍历

// 计算 n! 末尾有几个0
function zeros(n) {
  let count = 0
  while(n !== 0){
    n = parseInt(n/5)
    count += n
  }
  return count
}
/**
 * @param {number} k
 * @return {number}
 */
var preimageSizeFZF = function(k) {
  let count = 0, start = k * 4
  while (zeros(start) < k) {
    start ++
  }
  if (zeros(start) === k) {
    count = 5
  }
  return count
}

复杂度分析:

  • 时间复杂度:O(logk),其中 k 为题目给定数字。计算 zeros(k) 的时间复杂度为 O(logk)。
  • 空间复杂度:O(1)。

参考