力扣【阶乘问题】leetcode-172、阶乘后的零;leetcode-793、阶乘后K个零;

题目一: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、二分法 降维打击!

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_43473694/article/details/112557322