位运算: 查找按位XOR等于2的整数对问题 | 豆包MarsCodeAI刷题

60 阅读2分钟

题目链接

查找按位XOR等于2的整数对问题

前置知识

  • AND运算(按位与) : 二进制每位进行比较, 同时为1才为1, 其他情况均为0

    • 6 & 3 == 110 & 011 = 010
  • OR运算(按位或) : 二进制每位进行比较,同时为0才为0, 其他情况全为1

    • 6 & 3 == 110 | 011 = 111
  • XOR运算(按位异或) : 二进制每位进行比较, 不同时为1, 相同时为0

    • 6 & 3 == 110 ^ 011 = 101
  • 左移(<<) 将数字的二进制数往左移一位, 11变成110 等价于乘以2

  • 右移(>>) 将数字的二进制数往右移一位, 111变成011 等价于除以2

先来几个简单的位运算小技巧热热手:

  1. 如何得到一个数的二进制最低位? 比如2,二进制表示位10, 如何得到最低为1

    • 通过AND性质, 我们让2 和 1进行AND运算,
    • 即 10 & 01 得到 0; 3 == 011 & 001 = 1
    • 不管多少位,1都是n-1位0 + 1 只会对最后位产生影响
  2. 如何得到一个数的最低两位? n位?

    • 同理, 两位只需要AND上3(11)即可, n位AND上2n12^n-1
  3. 如何统计一个数中二进制位为1的数量?

    • 考虑第1个问题是如何判断最低位,我们只需要让数字每次移除最低位进行判断,知道数字为0即可
    • while(x) cnt += x & 1; x >>= 1

解题思路

  • 简化题意: 是否存在[l,r]区间内XOR=2的数字对

  • 考虑两个数XOR等于2, 2 == 10 前面添任意个0不会对值造成影响

  • 那么这两个数的前面n-2位必须保证相同,(XOR性质,相同才为0)

  • 比如当前数是7 我们要找一个数x 满足 7 XOR x == 2, 我们交换一下即 7 XOR 2 == x

  • 答案显而易见 111 XOR 010 == 101 =5 我们只需要判断5是否在[l,r]区间内

代码

int solution(int L, int R) {
    for(int i= L; i <= R; i++) {
        int v = i ^ 2;
        if(v >= L && v <= R) {
            return 1;
        }
    }
    return 0;
}

进阶

考虑算出区间内所有的XOR = 2 的数字对

  • 很简单,只需要在上面代码的基础上加上一个记录的数据结构,确保不重复计算即可
  • 比如 5 找到了 7 ,那么到7的时候就会再次找到5,set map都行

考虑算出区间内所有XOR = n的数字对

  • 只需要把 nums ^ 2 改为 nums ^ x 即可