面试经验(3)—位运算技巧

位运算基本操作总结


1、左移操作符
将A的二进制表示的每一位向左移B位,左边超出的位截掉,右边不足的位补0
A = 1100 B = 2
A << B = 110000

2、右移操作 A >> B
C语言:只有逻辑右移 A >> B
逻辑右移:将A的二进制表示的每一位向右移B位,右边超出的位截掉,左边不足的位补0。
A >> B = 11111111111111111111111111100000

3、按位与操作 a & b
将A和B的二进制表示的每一位进行与操作,只有两个对应的二进制位都为1时,结果位才为1,否则为0.
A = 001010
B = 101100
A & B = 001000

4、按位或操作 a | b
将A和B的二进制表示的每一位进行或操作,只要两个对应的二进制位有一个为1,结果位就为1,否则为0.
A = 001010
B = 101100
A | B = 101110

5、按位非操作 ~ a
将A的二进制表示每一位进行取反操作,如果对应的二进制位为0,结果位为1,否则为0.
A = 00000000000000000000000000001010
~A = 11111111111111111111111111110101

6、按位异或操作 a ^ b
将A和B的二进制表示的每一位进行异或操作,如果对应的二进制位不同,结果位为1,否则为0.
A = 001010
B = 101100
A ^ B = 100110

应用实战技巧


1、技巧一
x & (x - 1) 用于消去x最后一位的1
x = 1100
x - 1 = 1011
x & (x - 1) = 1000

应用一
用 O(1) 时间检测整数 n 是否是 2 的幂次。
http://www.lintcode.com/zh-cn/problem/o1-check-power-of-2/
思路解析:
N如果是2的幂次,则N满足两个条件。
1.N >0
2.N的二进制表示中只有一个1
因为N的二进制表示中只有一个1,所以使用N & (N - 1)将N唯一的一个1消去,应该返回0。

应用二
计算在一个 32 位的整数的二进制表式中有多少个 1。
http://www.lintcode.com/zh-cn/problem/count-1-in-binary/
思路解析:
由x & (x - 1)消去x最后一位的1可知。不断使用 x & (x - 1) 消去x最后一位的1,计算总共消去了多少次即可。

应用三
如果要将整数A转换为B,需要改变多少个bit位?
http://www.lintcode.com/zh-cn/problem/flip-bits/
解题思路:
这个应用是上面一个应用的拓展。
思考将整数A转换为B,如果A和B在第i(0<=i<32)个位上相等,则不需要改变这个BIT位,如果在第i位上不相等,则需要改变这个BIT位。所以问题转化为了A和B有多少个BIT位不相同。联想到位运算有一个异或操作,相同为0,相异为1,所以问题转变成了计算A异或B之后这个数中1的个数

2、技巧二
使用二进制进行子集枚举

应用一
给定一个含不同整数的集合,返回其所有的子集。
http://www.lintcode.com/zh-cn/problem/subsets/
解题思路:
思路就是使用一个正整数二进制表示的第i位是1还是0,代表集合的第i个数取或者不取。
所以从0到2^n-1总共2^n个整数,正好对应集合的2^n个子集。
S = {1,2,3}
N bit Combination
0 000 {}
1 001 {1}
2 010 {2}
3 011 {1,2}
4 100 {3}
5 101 {1,3}
6 110 {2,3}
7 111 {1,2,3}

3、技巧三
a ^ b ^ b = a

应用一
数组中,只有一个数出现一次,剩下都出现两次,找出出现一次的数
http://www.lintcode.com/en/problem/single-number/
思路解析:
因为只有一个数恰好出现一个,剩下的都出现过两次,所以只要将所有的数异或起来,就可以得到唯一的那个数。

猜你喜欢

转载自blog.csdn.net/daidaihema/article/details/79534219
今日推荐