x & (x-1) 和 x & (-x)

x & (x-1)


x 的 二进制显示是 (1000……1000)2
则(x-1) 的二进制显示就是把从右往左数的第一个1变成0,后面都变成1 : (1000……0111)2
x&(x-1) 相当于把 x 的最后一位1去掉

1.判断x是否是2的n次方


假如x是2的n次方,则x可以表示为(1000……0000)2, 对应的 x-1 表示为 (0111……1111)2
此时 x&(x-1) = 0.
于是乎 x&(x-1) = 0代表 x 是 2 的 n 次方,或 x 能被 2 整除

2.统计x的二进制表示中1的个数

每执行一次x&(x-1), x中就少了一个1

int func(x) 
{ 
    int countx = 0; 
    while(x) 
    { 
          countx ++; 
          x = x&(x-1); 
     } 
    return countx; 
} 

3.统计0<=i<=nums范围内的二进制数的1的个数

Leetcode338. 比特位计数
i & (i - 1)可以去掉i最右边的一个1(如果有),因此 i & (i - 1)是比 i 小的,而且i & (i - 1)的1的个数已经在前面算过了,所以i的1的个数就是 i & (i - 1)的1的个数加上1

class Solution {
public:
    vector<int> countBits(int num) {
        vector<int> ans(num + 1, 0);
        for(int i = 1; i <= num; ++i){
            ans[i] = ans[i & (i-1)] + 1;
        }
        return ans;
    }
};

4.只遍历一个数二进制位为1的部分

461. 汉明距离

class Solution {
public:
    int hammingDistance(int x, int y) {
        int ans = 0;
        int s = x ^ y;
        while (s) {
            ans++;
            s &= s - 1;
        }
        return ans;
    }
};

x&(-x)

这个操作又称 lowbit, 在树状数组里会用到

lowbit(x)=2^p, P是指将x转化为二进制之后从右往左数第一个一的位置。

posted @ 2020-12-06 17:17  miyanyan  阅读(117)  评论(0编辑  收藏  举报