五月集训(第10天)— 位运算
位运算
1. 191. 位1的个数
思路:
利用位运算统计1的个数
int hammingWeight(uint32_t n) {
int ans = 0;
while (n) {
ans += (n&1);
n >>= 1;
}
return ans;
}
2. 461. 汉明距离
思路:
直接位移统计汉明距离,要注意是最大的一个数为0时才停止比较,否则统计不全。
int hammingDistance(int x, int y){
int cnt = 0;
while (x || y) {
if ((x&1) != (y&1)) cnt++;
x >>= 1;
y >>= 1;
}
return cnt;
}
思路:
利用异或性质统计
int hammingDistance(int x, int y){
int cnt = 0;
while (x || y) {
cnt += ( (x&1) ^ (y&1) );
x >>= 1;
y >>= 1;
}
return cnt;
}
3. 136. 只出现一次的数字
思路:
利用异或性质,出现两次的数异或之后为0,所有数异或后就剩出现奇数次的数的异或值,此题中为只出现一次的数字。
int singleNumber(int* nums, int numsSize){
int ans = 0;
for (int i = 0; i < numsSize; i++) ans ^= nums[i];
return ans;
}
4. 137. 只出现一次的数字 II
思路:
利用两位二进制数a[i]b[i]记录第i位出现次数。00 -> 01 -> 10 -> 00
b = (b ^ nums[i]) & ~a;
a = (a ^ nums[i]) & ~b;
示例:[2,2,3,2]
a = 0 b = 0 num = 2b = (00B ^ 10B) & 11B = 10B; a = (00B ^ 10B) & 01B = 00B
a = 0 b = 2 num = 2b = (10B ^ 10B) & 11B = 00B; a = (00B ^ 10B) & 11B = 10B
a = 2 b = 0 num = 3b = (00B ^ 11B) & 01B = 01B; a = (10B ^ 11B) & 10B = 00B
a = 0 b = 1 num = 2b = (10B ^ 10B) & 11B = 00B; a = (00B ^ 10B) & 11B = 00B
整个操作过程就是在找是否有1出现:
step1: 发现a=0 b=0没有1,将b先置为1,然后a发现b=1,有1了,将a置为0
step2: a=0 b=1有1了,将b先置为0,然后a发现b=0,没有1了,将a置为0
step3: 发现a=1 b=0有1了,将b先置为0,然后a发现a=1,有1了,将a置为0
int singleNumber(int* nums, int numsSize){
int a = 0, b = 0;
for (int i = 0; i < numsSize; i++) {
b = (b ^ nums[i]) & ~a;
a = (a ^ nums[i]) & ~b;
}
return b;
}

浙公网安备 33010602011771号