2.1 求二进制数中的1的个数
最优解法:复杂度为O(k) k为二进制中1的个数
public int count(int n){
int num=0;
while(n){
//从后往前数‘1’的个数
//n&(n-1)这种方式可以消去一个‘1’
//e.g. 10000&01111=00000
n&=(n-1);
num++;
}
return num;
}
扩展问题2
给定两个正整数A和B,整数A和B的二进制表示中有多少位是不同的?
思路:异或
public int diff(int A,int B){
int num=A^B;
return count(num);
}
2.2不要被阶乘吓倒
问题
1、给定一个整数N,N!的末尾有多少个0?
2、求N!的第二进制中最低位1的位置
对于问题1
思路:能够产生0的有10和5*2。其中10也是由5*2构成,所以数5就可以(2出现的次数肯定比5多),也就是N!的5的质因数的个数。
所以最终结果=N/55+N/5252+N/5353+….
public int count( int N){
int res=0;
while(N){
N=N/5;
res+=N;
}
return res;
}
对于问题2
思路:求二进制中最低位1的位置,其实也是数二进制末尾的0的个数,0的个数+1也就是最低位1的位置。
所以最终结果=N/22+N/2222+N/2323+….+1
public int count2(int N){
int res=0;
while(N){
N>>=1;
res+=N;
}
return res+1;
}
综上所述,对于求N!的x进制的末尾0的个数(或最低位1的位置),都是在计算N!的质因数x的个数。统一的公式结果=N/xx+N/x2x2+N/x3x3+….