leetcode刷题记录-172. 阶乘后的零

1,020 阅读3分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

前言

昨天的题目为中等,昨天有点事没有时间做每日一题,今天补上,昨天的这道题主要是关于数学思维上的锻炼,得透过题目去寻找有用的信息才能更好地解题

每日一题

昨天的题目是 172. 阶乘后的零,难度为中等

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

  • 提示 n! = n * (n - 1) * (n - 2) * ... * 3 * 2 * 1

 

示例 1:

输入:n = 3
输出:0
解释:3! = 6 ,不含尾随 0

示例 2:

输入:n = 5
输出:1
解释:5! = 120 ,有一个尾随 0

示例 3:

输入:n = 0
输出:0

 

提示:

  • 0 <= n <= 104

进阶: 你可以设计并实现对数时间复杂度的算法来解决此问题吗?

题解

数学解法

由于题目表示的是阶乘,这肯定是没有办法用暴力解法来进行计算的,因为阶乘轻轻松松就可以突破数字的上限,那么我们要做的就是要去找规律

首先来看一下,为什么阶乘后面会出现0,任何数乘以 10 末尾都会出现 0 ,也只能是乘以 10,乘以 20 可以看出 2*10 归根到底都是乘了 10.

image.png

然后 10 可以 看做 2 * 5 ,然后我们拿一个 5 的阶层做一下演示:5 * 4 * 3 * 2 * 1 。这就是 5 的阶层,那么他会出现几个零呢 -- 120 一个零 因为在这五个数中,存在着 一对 5 * 2 不论你是用 2 * 5 或者 4 * 5, 到底也是只能凑出来一对 ,因为 5 的个数远远小于 2 的个数

image.png

那么到这里思路就明确了,我们要求得阶层后面有几个零,其实就是去求这个阶层当中有几个 5 的倍数,像 25 就能够 分解出 5 * 5 那就是 2 个零,以此类推,我们需要去找到当前这个阶层,有几个数能分解出 5 来,他们分别能分解出几个 ,然后把它们加起来,就能够得到题目需要的答案了。

image.png

然后我们现在拿 125 来举个例子,在 125 的阶乘当中,总共会出现 像 5 ,10 , 15 ,20 这样的 5的倍数总共25 个,还有就是会提供两个 5*5 的,也就是 25 的倍数,比如 25 它是会提供两个 5 的,那么 在 125 的阶乘当中一共有 5 个会提供两个 5 ,那么就是 25 + 5 。最后,还有一个 125 ,它是等于 5*5*5 它会提供三个五,那么就是 25 + 5 + 1,那么我们就能够求出来 125 的阶乘后面会有 31 个 0。

接着我们把上面的想法转化成为代码

循环去判断 当前的 n 除以 5 会等一多少 ,第一次除以 5 就相当于与上面 125 的第一个计算,算出能提供一个 5 的数有几个,第二次再除以 5 就是计算能提供 2个5 的数,一次类推,一直知道 n 以及不能除以 5 了,就能够计算出,能提供多少个 5 。

/**
 * @param {number} n
 * @return {number}
 */
 var trailingZeroes = function(n) {
    let res = 0;
    while (n !== 0) {
        n = Math.floor(n / 5);
        res += n;
    }
    return res;
};

image.png