技巧1、消去 num 的最后一个1

num & (num - 1)

应用1:O(1)时间复杂度 判断2的n次幂:(二进制只有一个1)

由于2的N次方的数二进制表示是第1位为1,其余为0,而x-1(假如x为2的N次方)得到的数的二进制表示恰恰是第1位为0,其余为1,两者相与,得到的结果就为0,否则结果肯定不为0。
return ((num & (num - 1)) == 0) ? true : false;

应用2:一个 32 位整数的二进制表示中有多少个 1

  1. int count = 0;
  2. while (num != 0) {
  3. count++;
  4. num = num & (num - 1);
  5. }
  6. return count;

应用3:将整数A转换为B,需要改变多少个bit位

思考将整数A转换为B,如果A和B在第i(0 <= i < 32)个位上相等,则不需要改变这个BIT位,如果在第i位上不相等,则需要改变这个BIT位。所以问题转化为了A和B有多少个BIT位不相同。联想到位运算有一个异或操作,相同为0,相异为1,所以问题转变成了计算A异或B之后这个数中1的个数

  1. int count =0;
  2. num = A^B;
  3. while (num != 0) {
  4. count++;
  5. num = num & (num -1);
  6. }

技巧2、a^b^b=a; a^0 = a;

应用1: 数组中,只有一个数出现一次,剩下都出现二次,找出出现一次的。

只有一个数恰好出现一个,剩下的都出现过两次,所以只要将所有的数异或起来,就可以得到唯一的那个数。

  1. int a[7]={1,2,2,1,3,4,3};
  2. int ans=0;
  3. for(int i=0;i<7;i++){
  4. ans^=a[i];
  5. }

应用2: 数组中,只有一个数出现一次,剩下都出现三次,找出出现一次的。