boxmoe_header_banner_img

Hello! 欢迎来到星海博客!

文章导读

数组异或操作


avatar
XingHai 2026年3月9日 11

题目:

给你两个整数,n 和 start 。

数组 nums 定义为:nums[i] = start + 2*i(下标从 0 开始)且 n == nums.length 。

请返回 nums 中所有元素按位异或(XOR)后得到的结果

示例 :

输入:n = 5, start = 0
输出:8
解释:数组 nums 为 [0, 2, 4, 6, 8],其中 (0 ^ 2 ^ 4 ^ 6 ^ 8) = 8 。
     "^" 为按位异或 XOR 运算符。

题目来源:力扣1486

题解:

暴力法:

枚举 i=0,1,2,…,n−1,计算 start+2i 的异或和。(过于简单,重点讲解数学法)

复杂度分析

  • 时间复杂度:O(n)。
  • 空间复杂度:O(1)。

数学法:

背景知识:

记 ⊕ 为异或运算,异或运算有以下性质:

1.x⊕x=0
2.x⊕y=y⊕x
3.(x⊕y)⊕z=x⊕(y⊕z)
4.x⊕y⊕y=x
5.对于任意的 i 属于整数,有 2i⊕(2i+1)⊕(2i+2)⊕(2i+3)=0

关于第五条的解释:

当 i 为偶数时:由于 2i 和 2i+1 只有最低位不同,所以 2i ⊕ (2i+1) = 00001(2) = 1,然后利用结合律(第三条)将原式化为 (2i⊕(2i+1)) ⊕ ((2i+2)⊕(2i+3)) = 1 ⊕ 1 = 0。

start是偶数:

如果start是偶数,那么nums[i]也为偶数,例如 n=5, start=0,即 0,2,4,6,8

由于这些数二进制最低位都为0,所以可以将这些数右移一位(除以2),然后计算异或和,再把异或和左移一位(乘以2)就得到了答案:

0⊕2⊕4⊕6⊕8=(0⊕1⊕2⊕3⊕4)⋅2=4⋅2=8

start是奇数:

如果start是奇数,那么nums[i]也为奇数,例如 n=5, start=3,即3,5,7,9,11。

分两部分计算答案:

最低位:因为所有数最低为都为 1 ,所以答案最低位取决于有多少个 1 ,如果有奇数个 1 那么异或和是 1,偶数个 1 那么异或和为 0。

除最低位的其余位:先把这些数右移一位(除以2),然后计算异或和,再把异或和左移一位(乘以2),最后加上最低位就得到最后的答案:

3⊕5⊕7⊕9⊕11=(1⊕2⊕3⊕4⊕5)⋅2+1=1⋅2+1=3

合二为一:

无论 start 是偶数还是奇数,都可以用同一个规则计算。

设 a=⌊2/start​⌋,b 为异或和的最低位。只有 n 和 start 都为奇数时 b=1,其余情况 b=0。那么异或和等于

start⊕(start + 2*1)⊕(start + 2*2)⊕(start + 2*3)⊕···⊕(start + 2*(n-1))右移一位得(start/2)⊕(start/2 + 1)⊕(start/2 + 2)⊕(start/2 + 3)⊕···⊕(start/2 + (n-1)),再左移加上最低位得(start/2)⊕(start/2 + 1)⊕(start/2 + 2)⊕(start/2 + 3)⊕···⊕(start/2 + (n-1)) *2 + b = a⊕(a + 1)⊕(a + 2)⊕(a + 3)⊕···⊕(a + (n-1)) + b

由第四条定律得a⊕(a + 1)⊕(a + 2)⊕(a + 3)⊕···⊕(a + (n-1)) = (0⊕1⊕2⊕···⊕(a-1)) ⊕ (0⊕1⊕2⊕··· ⊕ (a-1)⊕a⊕(a+1)⊕(a+2) ⊕ ··· ⊕ (a+(n-1))

按照 n 模 4 的结果分类,去计算 0 到 n 的异或和:

  • 当 n = 4k + 1 (例如1,5,9)时,两个数一组一共有(4k + 1 + 1) / 2 =2k + 1组,所以有奇数个1,答案为1。
  • 当 n = 4k + 2 (例如2,6,10),答案为(0⊕1⊕2⊕···⊕4k+1)⊕4k + 2 = 1 ⊕ (4k + 2) = 4k + 2 + 1 = 4k + 3 = n + 1。
  • 当 n = 4k + 3 (例如3,7,11),两个为一组一共有(4k+3+1)/2 = 2k + 2组,有偶数个1,答案为0。
  • 当 n = 4k + 4 (例如4,8,12)时,答案为(0⊕1⊕2⊕···⊕4k+3) ⊕ 4k + 4 = 0 ⊕ 4k + 4 = 4k + 4 = n。

综上所述:

class Solution {
    int xor_n(int n) {
        switch (n % 4) {
            case 0: return n;
            case 1: return 1;
            case 2: return n + 1;
            default: return 0;
        }
    }
}

public:
    int xorOperation(int n, int start) {
        int a = start / 2;
        int b = n & start & 1; // 都为奇数才是 1
        return (xor_n(a + n - 1) ^ xor_n(a - 1)) * 2 + b;
    }
};

复杂度分析

  • 时间复杂度:O(1)。
  • 空间复杂度:O(1)。


评论(0)

查看评论列表

暂无评论


发表评论

表情 颜文字
插入代码