对于一个正整数 n,如果对这个正整数执行 n &= (n - 1); 的代码,将会得到一个整数m
n 和 m的关系:n 的二进制表示 与 m的二进制表示中除了n最右边的1取值不同,其他都相同
比如114514 和 114512 的二进制表示中第2位(从低位往高位数)不同,其它位都相同
所以这个规律有什么用?当然是可以用来求解 leetcode 191. 位1的个数!
class Solution {
public:
int hammingWeight(int n) {
int ret = 0;
while(n){
n &= (n - 1);
ret++;
}
return ret;
}
};
所以这个规律还有什么用?当然是可以用来求解 leetcode 338. 比特位计数!
但是!338这个还可以用动态规划 + 位运算的解法进行求解
通过打表发现:
n的二进制表示中1的个数就是 n & (n - 1) 这个数的二进制表示中1的个数加一
class Solution {
public:
vector<int> countBits(int n) {
vector<int> ret(n + 1, 0);
for(int i = 1; i <= n; i++){
ret[i] = ret[i & (i - 1)] + 1;
}
return ret;
}
};
注意n & (n - 1) < n 对于任意的正整数 n 是恒成立的