位运算(二)

1:交换数字

 

 解题思路:假如我们现在有俩数字:a,b;

 我们可以令a=a^b;

                   b=a^b=a^(b^b)=a^0=a;

                   a=a^b=a^b^a=a^a^b=b;

具体代码如下:

 

 

2:汉明距离

 

 

 解题思路:首先将两个整数进行异或,如果对应的二进制位不同则为1,所以我们只需判断异或后的结果1的个数即可。

 代码如下:

 

 

 

3.交替位二进制数

 

 解题思路:我们知道0-0与1-1想&结果为0,1-1与1-1相&结果为3,所以我们可以把该正整数与3想&,如果结果不为0且不为3

则直接return flase,否则继续右移并与3想与,直到该数为0。

 代码如下:

 

 

 

4:找出所有子集的异或总和再求和

 

  解题思路:我们可以用位运算进行状态压缩,就以nums=[1,3]为例,数组中的元素都有选和不选两种状态,因此集合的

个数为num.size()的二次方(即1<<nums.size()),我们计为n;并且我们可以使用0~n-1表示每个集合中元的元素。例如在

本题中n=4,0的二进制为0-0,代表数组中俩数都没有被选;1的二进制位0-1,表示该集合只含有数组第1个元素;2的

二进制位1-0,表示该集合只有数组第2个元素;3的二进制为1-1,表示该集合含有数组中2个元素。

   根据上面所述我们可以知道我们只需要把0~n-1分别转换成2进制数字,并判断该2进制数字中,有哪几位是1,即能表示一个集合,

该集合含有这几位对应数组下标的元素。

具体代码如下:

 

 5:两数之和

 

 

 解题思路:

虽然题目只要求了不能使用运算符 + 和 -,但是原则上来说也不宜使用类似的运算符+=和 -= 以及sum 等方法。于是,我们使用位运算来处理这个问题。

首先,考虑两个二进制位相加的四种情况如下:

0 + 0 = 0
0 + 1 = 1
1 + 0 = 1
1 + 1 = 0 (进位)
可以发现,对于整数 a 和 b:

在不考虑进位的情况下,其无进位加法结果为a⊕b。

而所有需要进位的位为 a & b,进位后的进位结果为(a & b) << 1。

于是,我们可以将整数 a和 b 的和,拆分为 a 和 b 的无进位加法结果与进位结果的和(因此这是一个递归过程直到进位为0,返回结果)

具体代码如下:

 

posted @ 2022-04-28 21:03  伞兵1号  阅读(70)  评论(0)    收藏  举报