位运算 |
||
0. 原理 |
|
|
1. 统计两个数的二进制表示有多少位不同 |
第一次可做出Ok |
|
2. 数组中唯一一个不重复的元素 |
第一次可做出Ok |
|
3. 找出数组中缺失的那个数 |
第一次可做出,类上 |
|
4. 数组中不重复的两个元素 |
第一次未做出 |
※ |
5. 翻转一个数的比特位 |
思考后可做出 |
|
6. 不用额外变量交换两个整数 |
|
|
7. 判断一个数是不是 2 的 n 次方 |
做法可简化 |
※ |
8. 判断一个数是不是 4 的 n 次方 |
思考后可做出 |
|
9. 判断一个数的位级表示是否不会出现连续的 0 和 1 |
有其他做法可参考 |
※ |
10. 求一个数的补码 |
思考后可做出 |
※ |
11. 实现整数的加法 |
有其他做法可参考 |
※ |
12. 字符串数组最大乘积 |
思考后可做出 |
※ |
13. 统计从 0 ~ n 每个数的二进制表示中 1 的个数 |
第一次未做出 |
※ |
基本原理
0s 表示一串 0,1s 表示一串 1。
x ^ 0s = x x & 0s = 0 x | 0s = x
x ^ 1s = ~x x & 1s = x x | 1s = 1s
x ^ x = 0 x & x = x x | x = x
1^1^2 = 2
01011011 &
00111100
--------
00011000
01011011 |
00111100
--------
01111111
位与运算技巧
移位运算
mask 计算
461. Hamming Distance (Easy)
https://leetcode-cn.com/problems/hamming-distance/
136. Single Number (Easy)
https://leetcode-cn.com/problems/single-number/
268. Missing Number (Easy)
https://leetcode-cn.com/problems/missing-number/
class Solution {
public:
int missingNumber(vector& nums) {
int ret=nums.size();
for(int i=0;i
260. Single Number III (Medium)
https://leetcode-cn.com/problems/single-number-iii/
两个不相等的元素在位级表示上必定会有一位存在不同。
将数组的所有元素异或得到的结果为不存在重复的两个元素异或的结果。
diff &= -diff 得到出 diff 最右侧不为 0 的位,也就是不存在重复的两个元素在位级表示上最右侧不同的那一位,利用这一位就可以将两个元素区分开来。
class Solution {
public:
vector singleNumber(vector& nums) {
vector ret(2,0);
int dif=0;
for(int num:nums) dif^=num;
dif&=(-dif);
for(int num:nums)
if((num&dif)==0) ret[0]^=num;
else ret[1]^=num;
return ret;
}
};
190. Reverse Bits (Easy)
https://leetcode-cn.com/problems/reverse-bits/
a = a ^ b;
b = a ^ b; //原a
a = a ^ b; //原b
或者
a = a + b;
b = a - b; //原a
a = a - b; //原b
231. Power of Two (Easy)
https://leetcode-cn.com/problems/power-of-two/submissions/
class Solution {
public:
bool isPowerOfTwo(int n) {
return n>0&&(n&(n-1))==0;
}
};
342. Power of Four (Easy)
https://leetcode-cn.com/problems/power-of-four/
693. Binary Number with Alternating Bits (Easy)
https://leetcode-cn.com/problems/binary-number-with-alternating-bits/submissions/
对于 1010 这种位级表示的数,把它向右移动 1 位得到 101,这两个数每个位都不同,因此异或得到的结果为 1111。
class Solution {
public:
bool hasAlternatingBits(int n) {
long long a=n^(n>>1);
return (a&(a+1))==0;
}
};
class Solution {
public:
bool hasAlternatingBits(int n) {
for(int i=n>>1,ret=n&1;i>0;ret=i&1,i>>=1)
if((i&1)^ret==0) return false;
return true;
}
};
476. Number Complement (Easy)
https://leetcode-cn.com/problems/number-complement/
class Solution {
public:
int findComplement(int num) {
int ret=0;
for(int j=1;num>0;num>>=1,j<<=1)
if((num&1)==0) ret|=j;
return ret;
}
};
371. Sum of Two Integers (Easy)
https://leetcode-cn.com/problems/sum-of-two-integers/submissions/
a ^ b 表示没有考虑进位的情况下两数的和,(a & b) << 1 就是进位。
递归会终止的原因是 (a & b) << 1 最右边会多一个 0,那么继续递归,进位最右边的 0 会慢慢增多,最后进位会变为 0,递归终止。
class Solution {
public:
int getSum(int a, int b) {
return (b==0)?a:getSum((a^b),((unsigned int)a&b)<<1);
}
};
318. Maximum Product of Word Lengths (Medium)
https://leetcode-cn.com/problems/maximum-product-of-word-lengths/
class Solution {
public:
int maxProduct(vector& words) {
size_t n=words.size(),ret=0;
vector w(n,0);
for(int i=0;i
338. Counting Bits (Medium)
https://leetcode-cn.com/problems/counting-bits/
对于数字 6(110),它可以看成是 4(100) 再加一个 2(10),因此 dp[i] = dp[i&(i-1)] + 1;
class Solution {
public:
vector countBits(int num) {
vector ret(num+1,0);
for(int i=1;i<=num;i++)
ret[i]=ret[i&(i-1)]+1;
return ret;
}
};