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.
然后 10 可以 看做 2 * 5 ,然后我们拿一个 5 的阶层做一下演示:5 * 4 * 3 * 2 * 1 。这就是 5 的阶层,那么他会出现几个零呢 -- 120 一个零 因为在这五个数中,存在着 一对 5 * 2 不论你是用 2 * 5 或者 4 * 5, 到底也是只能凑出来一对 ,因为 5 的个数远远小于 2 的个数
那么到这里思路就明确了,我们要求得阶层后面有几个零,其实就是去求这个阶层当中有几个 5 的倍数,像 25 就能够 分解出 5 * 5 那就是 2 个零,以此类推,我们需要去找到当前这个阶层,有几个数能分解出 5 来,他们分别能分解出几个 ,然后把它们加起来,就能够得到题目需要的答案了。
然后我们现在拿 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;
};