编程之美2.2,有两道关于阶乘的问题,第一个就是leetcode上的172题
172. Factorial Trailing Zeroes
Given an integer n, return the number of trailing zeroes in n!.
Note: Your solution should be in logarithmic time complexity.
1、分解因子, 当且仅当 因子中出现 一对 (2,5)时, 最后结果会增加一个 trailing zero.
2、2的个数永远多于5个个数.
3、计算5的个数时, 最简单的方法是 SUM(N/5^1, N/5^2, N/5^3...)
public static int trailingZeroes(int n) { int re=0; while(n>0){ re+=n/5; n/=5; } return re; }
第二题:求n!的二进制中表示最低位的1的位置。
求一个二进制数中最低一位1的位置,可以转化为求二进制数中右边起有多少个0,然后在加上1,就是第一个1的个数。
那么,求右边起0的个数怎么求呢,明显是判断(n&1)==0,每次右移以为,知道不等于1,循环的次数就是0的个数。也就是说,每次都出除以2,知道不能被2整除。所以其实就是含有质因数2的个数。
再回到这道题,按照上面的方法求n的阶乘中质因数2的个数,就是从1到n每个数含有质因数2的个数全部加起来,转换成公式就是(n/2)+(n/4)+(n/8)+(n/16)····,代码如下
public static int jiechentg(int n){ int re=0; while(n>0){ n>>=1; re+=n; } return re; }
关于公式(n/2)+(n/4)+(n/8)+(n/16)····的推倒,求质因数2的个数
(n/k)等于1,2,3···n中能被k整除的个数,
所以,1,2,3···n中,能被2整除的中含有1个2的质因数,能被4整除的含有2个2的质因数,能被8整除的含有3个依次类推他们相加就得到了(n/2)+(n/4)+(n/8)+(n/16)····
总结:遇到阶问题,直接乘上去肯定超时,要试着找到所求问题与阶乘的关系,然后因式分解