零、写在前面
这个系列不经常更新,今天这个题目又觉得有点意思,我们一起看一看,主要知识点在
《C语言入门100例》(第7例) n!
https://blog.csdn.net/WhereIsHeroFrom/article/details/118208252
一、主要知识点
1.给定 n,求 1 × 2 × 3 × ... × n 的乘积
int ans = 0,n; while(n) { ans *= n; --n; }
二、课后习题
面试题 16.05. 阶乘尾数
面试题 16.05. 阶乘尾数
https://leetcode-cn.com/problems/factorial-zeros-lcci/
思路
这道题就是让求尾数0的个数,要产生一个0,那么因子里必有一个5一个2,n!每两个数字就有一个为偶数,也就是包含2因子,但是每五个才包含一个5因子,所以我们统计多少个5末尾就会又多少个0。
如果一个数字是5的多少倍那么就会贡献多少个5因子,同时5^2会贡献两个,第一次算过了就可以只算贡献一个。5^3贡献的三个前两个被5^1和5^2给计算过了,所以也是加一次就好了。代码如图。
int trailingZeroes(int n){ int i = 0,ans = 0,temp = 1; for(i = 0;temp <= n && temp < 429496730;i ++){ temp *= 5; //穷举所有的5的指数 ans += n / temp; //计算5因子个数 } return ans; }
结果分析
我就是觉得4ms和0ms没差别-.-
793. 阶乘函数后 K 个零
793. 阶乘函数后 K 个零
https://leetcode-cn.com/problems/preimage-size-of-factorial-zeroes-function/
思路
这道题和第一题很类似,只要找出来相应的x拥有k个零那么就返回5,否则就是0,因为一定有5a ,5a+1,5a+2.5a+3,5a+4五个数字拥有相同的0的个数。
利用二分查找相应的x,差找范围是 k- 5*k +1,原因是含有k个零的元素最小是k,最大不超过5*k+1,原因是5*k就含有k个5的倍数,这个数字含有的零元一定比k多。+1是为了统一0的处理。
long zeta(long x){ //判断x又多少个0 if(!x) return 0; //递归出口 return x / 5 + zeta(x / 5); //分解x!中包含的5因子个数 } int preimageSizeFZF(int k){ long low = k,high = (long)k * 5 +1;//从k-k*5+1中寻找是否有满足要求的解 while(low < high){ long mid = (low + high) /2; long zmi = zeta(mid); if(zmi == k) return 5; //找到则返回 else if(zmi < k) low = mid +1; else high = mid; } return 0; //没找到返回0 }
结果分析
凑合玩吧。。
写在最后
这个系列确实是不怎么更新,但是我觉得有难度的题都会进行更新,所以还是建立一个合集,有需要的欢迎关注。