求二进制中1的个数:
解法一:O(logn)
int solve(int data)
{
int cnt = 0;
while(data){
if(data & 1) cnt ++;
data = data >> 1;
}
return cnt;
}
解法二:O(M) M为1的个数
int solve(int data)
{
int cnt = 0;
while(data){
data &= data - 1;
cnt ++;
}
return cnt;
}
精髓 : v & (v - 1)
v & (v + 1) 可以去掉末尾的连续多个1(如果末尾没有1 则不用去掉)
扩展问题:
把A变成B需要改变多少位?
<=>先问题等价转化:A与B有多少位不同? 显然是先异或,然后数1的个数就好了。下面附一份代码吧。
int solve(int a, int b)
{
int cnt = 0, data = a ^ b;
while(data){
data &= data - 1;
cnt ++;
}
return cnt;
}