每日一道 LeetCode (41):阶乘后的零
每天 3 分钟,走上算法的逆袭之路。
前文合集
代码仓库
GitHub: https://github.com/meteor1993/LeetCode
Gitee: https://gitee.com/inwsy/LeetCode
题目:阶乘后的零
给定一个整数 n,返回 n! 结果尾数中零的数量。
示例 1:
输入: 3
输出: 0
解释: 3! = 6, 尾数中没有零。
示例 2:
输入: 5
输出: 1
解释: 5! = 120, 尾数中有 1 个零.
说明: 你算法的时间复杂度应为 O(log n) 。
解题方案一:暴力计算
看到这道题,常人的思维最少应该有先把 n! 算出来,再通过 /10 来计算末尾有多少个 0 。
// 暴力硬算
public int trailingZeroes(int n) {
// 先定义第一个数字
BigInteger bi = BigInteger.ONE;
for (int i = 2; i <= n; i++) {
bi = bi.multiply(BigInteger.valueOf(i));
}
// 定义 0 出现的次数
int count = 0;
while (bi.mod(BigInteger.TEN).equals(BigInteger.ZERO)) {
bi = bi.divide(BigInteger.TEN);
count++;
}
return count;
}
我累个擦,直接超时了,然后看下测试用例,竟然执行到一个 4327 的数字,拿 4 位数出来算阶乘,就是计算机来算我都觉得累得慌,这个测试用例我服了,甘拜下风。
么得办法了,看答案吧,我这个智商也就只能想到这种方案了。
解题方案二:计算因子 5
先想一下,啥情况下能产生 0 ,最小的产生因子是 2 * 5 。
借用一个答案上的示例,42 * 75 = 3150
,这个算式可以拆解如下:
42 = 2 * 3 * 7
75 = 3 * 5 * 5
42 * 75 = 2 * 3 * 7 * 3 * 5 * 5
这里面只出现了一对 2 和 5 ,所以结果只有一个 0 。
接着看另一个案例,比如求 19! ,这里面包含 5 的因子有 5 、10 、15 ,包含 2 的因子有2、4、6、8、10、12、14、16、18 。
可以看到的规律是每 5 个数字就会有一个包含 5 的因子,而在这 5 个数中间,肯定至少有一个包含 2 的因子,实际上是有 2 个,所以就不需要考虑 2 这个因子了,单纯的考虑 5 就好了,那么算法就演变成了我们需要寻找包含 5 的因子,代码如下:
// 计算因子 5
public int trailingZeroes_1(int n) {
int count = 0;
for (int i = 5; i <= n; i += 5) {
int current = i;
while (current % 5 == 0) {
count++;
current /= 5;
}
}
return count;
}
结果又超时了,我心态崩了啊,答案给的都是超时,看这个输入的数字, TM 18 亿,还敢输入数字再大点嘛。
接着刚才的答案往下看。
答案上还给出了另一种方案,不需要每次检查是否可以被 5 整除,还可以直接检查是否可以被 5 的次幂整除:
public int trailingZeroes_2(int n) {
int count = 0;
for (int i = 5; i <= n; i += 5) {
int powerOf5 = 5;
while (i % powerOf5 == 0) {
count += 1;
powerOf5 *= 5;
}
}
return count;
}
这个方案实际上和上面的方案是一样的,没什么本质的区别。
解题方案三:高效的计算因子 5
接着往下看,更加高效的计算方案。
看下面这个阶乘方案:
n! = 1 * 2 * 3 * 4 * (1 * 5) * ... * (2 * 5) * ... * (3 * 5) *... * n
我们的目标是计算出现了多少个 5 ,从上面这个公式看下来,每隔 5 个数就会出现一次,那么我们使用 n / 5
就可以计算出来。
但是还没有结束,接着看下面的公式变化:
... * (1 * 5) * ... * (1 * 5 * 5) * ... * (2 * 5 * 5) * ... * (3 * 5 * 5) * ... * n
从这个公式可以看出来,每隔 5 个数,出现一个 5 ,每隔 25 个数,出现 2 个 5 ,每隔 125 个数,出现 3 个 5 ,以此类推。。。
最终出现 5 的个数就是 n / 5 + n / 25 + n / 125 ...
。
题解到这一步就能开始写程序了:
// 更加高效的计算因子 5
public int trailingZeroes_3(int n) {
int count = 0;
while (n > 0) {
n /= 5;
count += n;
}
return count;
}
终于出结果了,我太难了,不过 LeetCode 把这道题的难度定成简单真的合适么。。。
每日一道 LeetCode (41):阶乘后的零的更多相关文章
- LeetCode 172. 阶乘后的零(Factorial Trailing Zeroes)
172. 阶乘后的零 172. Factorial Trailing Zeroes 题目描述 给定一个整数 n,返回 n! 结果尾数中零的数量. LeetCode172. Factorial Trai ...
- Leetcode 172.阶乘后的零
阶乘后的零 给定一个整数 n,返回 n! 结果尾数中零的数量. 示例 1: 输入: 3 输出: 0 解释: 3! = 6, 尾数中没有零. 示例 2: 输入: 5 输出: 1 解释: 5! = 120 ...
- Java实现 LeetCode 172 阶乘后的零
172. 阶乘后的零 给定一个整数 n,返回 n! 结果尾数中零的数量. 示例 1: 输入: 3 输出: 0 解释: 3! = 6, 尾数中没有零. 示例 2: 输入: 5 输出: 1 解释: 5! ...
- 【每天一题】LeetCode 172. 阶乘后的零
开源地址:点击该链接 题目描述 https://leetcode-cn.com/problems/factorial-trailing-zeroes 给定一个整数 n,返回 n! 结果尾数中零的数量. ...
- 每日一道 LeetCode (3):回文数
前文合集 每日一道 LeetCode 文章合集 题目:回文数 题目来源:https://leetcode-cn.com/problems/palindrome-number/ 判断一个整数是否是回文数 ...
- 每日一道 LeetCode (5):最长公共前缀
前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub: https://github.com/meteor1993/LeetCode Gitee: https://gitee.com ...
- 每日一道 LeetCode (8):删除排序数组中的重复项和移除元素
每天 3 分钟,走上算法的逆袭之路. 前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub: https://github.com/meteor1993/LeetCode Gitee ...
- 每日一道 LeetCode (14):数组加一
每天 3 分钟,走上算法的逆袭之路. 前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub: https://github.com/meteor1993/LeetCode Gitee ...
- 每日一道 LeetCode (15):二进制求和
每天 3 分钟,走上算法的逆袭之路. 前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub: https://github.com/meteor1993/LeetCode Gitee ...
随机推荐
- 010_go语言中的maps映射(字典)
代码演示 package main import "fmt" func main() { m := make(map[string]int) m["k1"] = ...
- “随手记”开发记录day08
今天完成了关于统计页面中的关于每月支出和每月收入的页面
- Web For Pentester 学习笔记 - XSS篇
XSS学习还是比较抽象,主要最近授权测的某基金里OA的XSS真的实在是太多了,感觉都可以做一个大合集了,加上最近看到大佬的博客,所以这里我也写一个简单的小靶场手册,顺带着也帮助自己把所有XSS的方式给 ...
- [leetcode/lintcode 题解] Google面试题:合法组合
给一个单词s,和一个字符串集合str.这个单词每次去掉一个字母,直到剩下最后一个字母.求验证是否存在一种删除的顺序,这个顺序下所有的单词都在str中.例如单词是’abc’,字符串集合是{‘a’,’ab ...
- 初识HTML(二)
目录 HTML表格 HTML列表 HTML表格 表格主要显示.展示数据. 表格基本语法:<table>定义一个表格,<tr>定义表格中的一行,<td>定义一行中的某 ...
- C#LeetCode刷题之#48-旋转图像(Rotate Image)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3668 访问. 给定一个 n × n 的二维矩阵表示一个图像. 将 ...
- vue cli 中关于vue.config.js中chainWebpack的配置
Vue CLI 的官方文档上写:调整webpack配置最简单的方式就是在vue.config.js中的configureWebpack选项提供一个对象. Vue CLI 内部的 webpack 配置 ...
- 总结关于Ubuntu 安装 Docker 配置相关问题及解决方法
总结关于Ubuntu 安装 Docker 配置相关问题及解决方法 Tomcat 示例 软件镜像(xx安装程序)----运行镜像----产生一个容器(正在运行的软件,运行的xx): 步骤: 1.搜索镜像 ...
- Jmeter 常用函数(30)- 详解 __if
如果你想查看更多 Jmeter 常用函数可以在这篇文章找找哦 https://www.cnblogs.com/poloyy/p/13291704.html 作用 判断给定条件是否成立 语法格式 ${_ ...
- Matplotlib&Numpy
Matplotlib 是专门用于开发2D图表(包括3D图表) 以渐进.交互式方式实现数据可视化 实现一个简单的Matplotlib画图 ①导入:matplotlib.pytplot包含了一系列类似于m ...