题目一:172、阶乘后的零
给定一个整数 n,返回 n! 结果中,尾数中零的数量
举一个栗子:6!=【 1 * 2 * 3 * 4 * 5 * 6 】
6!= 720
所以的话就是返回1,因为720 后面只有一个0
1、那么应该怎么做呢?
乍一看,感觉问题很复杂,其实只要冷静下来,一步一步简化,结果是十分明了的~
第一个想法:首先把阶乘算出来,然后从前到后每一位都遍历吗?
这个方法肯定是不可取的,复杂度太高了。
2、我们只需要简单分析一下
题目要求看 0 的数量 ,
1、末尾的0 是从哪里来的?
肯定是乘以 10 得来的!
2、10 是从哪里来的?
10 = 2 * 5;也就是说,10 只能从2 和5 相乘得到;
只看 2 和 5 出现的次数,因为只有2 和 5 才会产生 10 ,才会有 0 的呀!
当然,这里要多说一嘴,0 就不要考虑了,因为 0!= 1 啊。
3、问题就做可以做第一次简化:
判断n!= 【1 * 2 * 3 * …… * n 】 中到底有多少个 2 和 5 的组合?
随后,我们继续分析,还可以继续优化;
10 从 2 * 5 中得到,单单一个 2 或者 一个 5 ,或者和其它组合,都是没法产出 10 的1、只有一个2 一个5 结合在一起才行
2、进一步,2多 5 少呢?5多 2 少呢?
自然是根据少的来嘛!
4、我们再举几个栗子分析
6!=【 1 * 2 * 3 * 4 * 5 * 6 】 6 = 2 * 3;
所以两个 2 ,一个5,于是一个10,
10! =【 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10】
2 4 6 8 10 都可以出来2 ,一共七个2;5= 1 *5;10 = 2 * 5;
一共两个5;所以两个10
不难看出,2 的个数是 大于等于 5 的个数的;这也是我们第二次简化的依据
5、问题就做第二次简化:
判断 n!= 【1 * 2 * 3 * …… * n 】 中到底乘了多少个 5
这样一来,问题就简单很多了!
注意:问题到这里就分析完了吗?当然没有,我们还应该注意以下这样的数字:
10 = 2 * 5 贡献1个5
5 = 3 * 5 贡献1个5
25 = 5 * 5 贡献2个5
125 = 5 * 5 * 5 贡献3个5
以此类推~ 这些数字都是我们应该处理的
有了上述的分析和注意点,我们便可以写出代码了
class Solution {
public:
int trailingZeroes(int n) {
int count = 0;
while(n >= 5) {
count += n / 5;
n /= 5;
}
return count;
}
};
题目二:793、阶乘后K个零
1、题目描述:给你一个数字 k ,找出有多少个非负整数 n,使得 n! 后方,有k个0注意: k 是范围在 [0,10^9]的整数
说实话这个题有一点数学了,但是依旧是那一个解题步骤逐步分析!简化!
简单分析:通过上一题,我们可以知道,只有10的倍数,才会有0每有一对2和5的组合,n! 后面就会多一个0而 n!展开中,2个数比5个数多问题就转化为 n! 有多少个 5 作为因子
既得: n 的阶乘末尾 0 的个数 为:k;
满足公式:k = n/5 + n/5^2 + n/5^3 + ……
根据条件: k 是范围在 [0,10^9]的整数
得到:n < 5 *10^9
2、n 每+5,阶乘就会至少多乘一个5,末尾就会至少多一个0
有解,那就是5个,如果无解就是0个!
只有这两个情况!
n可以取这么大的数?该如何解题呢?
3、二分法 降维打击!