编程之美 2.2

(1)

阶乘确实是一个让人头疼的问题,其本身的实现很简单,它的问题在于结果膨胀式的增长会造成n!的结果的溢出。2.2给出了几种从数学角度出来的思路,可以避免上面的问题发生。

首先要清楚的一个问题就是质因数分解给定任意一个整数w,那么w一定可以分解成w=2^x * 3^y * 5^m……这种形式,这个数学理论是解决此类问题的关键。

接着分析因为10进行质因数分解的结果为 10 = 2 * 5, 所以每一对2和5相乘就会在其n!的末尾添加上一个0,因而n!末尾0的个数同2、5的对数相同,即末尾0的个数count = min(x,m);

其实分析到这里可以先得出一个解法了就是分别统计2和5的幂然后比较哪个比较小,min的值便是我们要取得值。

但是书中又讲到了一个不是定理的定理:在阶乘n!的质因数分解中2的指数不会小于5的指数。 因而这个问题直接便转化为求5的指数,具体做法很容易详情见解法一书中;

很明显解法一的时间复杂度是O(nlog5n),这个算法在很大程度上还是取决于n的大小;

解法2是一个很精彩的做法,时间复杂度优化到了O(log5n),阶乘n!中最后一个数n反应了前面数的一些基本情况,比如说21/5=4说明就是在21之前一共出现过4次5,这样就避免了遍历一遍n的时间。又比如25/5=5,这说明从1到25已经出现了5个5,且结果还是5说明25是两个5相乘得到的,所以是1+1+1+1+2=6,解法二已经是这个问题的极限优化解法。

判断n!可以被数k整除多少次?

num = [n/5] + [n/5^2] + …… + [n/5^m],n/5^m = 0

(2)

其实(1)和(2)是本质相同的两个问题,(2)就是找到在n!的质因数分解中2的指数。

    原文作者:Alex-Song
    原文地址: https://blog.csdn.net/qijizhen/article/details/19079087
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞