1486. 数组异或操作
1486. 数组异或操作
题目含义:根据整数 n n n 和 s t a r t start start 构造一个数组,数组元素为 n u m s [ i ] = 2 i + s t a r t , i ∈ [ 0 , n − 1 ] nums[i] = 2i + start, i \in [0,n-1] nums[i]=2i+start,i∈[0,n−1];最后返回这个数组全部元素的异或结果。
我们可以根据异或运算的性质实现时间复杂度为 O ( 1 ) O(1) O(1)。
记 ⊕ \oplus ⊕ 为异或运算,那么就有以下性质:
第 5 点性质,由于 x x x 为偶数时, x x x 和 x + 1 x+1 x+1 只有最低位不同,所以 x ⊕ ( x + 1 ) = 1 x \oplus (x+1) = 1 x⊕(x+1)=1;因此 0 ⊕ 1 ⊕ 2 ⊕ 3 = 1 ⊕ 1 = 0 0 \oplus 1 \oplus 2 \oplus 3 = 1 \oplus 1 = 0 0⊕1⊕2⊕3=1⊕1=0。
对于本题,我们需要求解 s t a r t ⊕ ( 2 + s t a r t ) ⊕ ( 4 + s t a r t ) ⊕ . . . ⊕ ( 2 ( n − 1 ) + s t a r t ) start \oplus (2 + start) \oplus (4 + start) \oplus ... \oplus (2(n-1) + start) start⊕(2+start)⊕(4+start)⊕...⊕(2(n−1)+start) 的结果。
观察公式可以知道,这些元素的奇偶性质相同,因此它们的二进制表示中的最低位或者均为 1,或者均为 0。于是我们可以把参与运算的数的二进制位的最低位提取出来单独处理。当且仅当 start 为奇数,且 n 也为奇数时,结果的二进制位的最低位才为 1,我们将最低位用 e e e 存储。
此时,当我们把每个元素右移一位(除以 2),再将 s = s t a r t 2 s = \frac{start }{2} s=2start,得到
s ⊕ ( 1 + s ) ⊕ ( 2 + s ) . . . ⊕ ( ( n − 1 ) + s ) ⋅ 2 + e s \oplus (1 + s) \oplus (2 + s) ... \oplus ((n-1) + s) \cdot 2 + e s⊕(1+s)⊕(2+s)...⊕((n−1)+s)⋅2+e
此时,我们需要求解 [ s , ( n − 1 ) + s ] [s, (n-1) + s] [s,(n−1)+s] 这个序列的异或结果。
根据性质 5,我们知道,连续四个整数的异或结果为 0,那么就有以下四种情况:
其中, s u m X o r ( x ) sumXor(x) sumXor(x) 是一个函数,表示 0 ⊕ 1 ⊕ 2 ⊕ . . . ⊕ x 0 \oplus 1 \oplus 2 \oplus ... \oplus x 0⊕1⊕2⊕...⊕x。
我们再进一步的化简:
当 x x x 为偶数时,所以 x ⊕ ( x + 1 ) = 1 x \oplus (x+1) = 1 x⊕(x+1)=1;
当 x = 4 k + 1 x=4k+1 x=4k+1,此时 x − 1 x-1 x−1 是偶数,所以化简结果为 1;
当 x = 4 k + 2 x=4k+2 x=4k+2,此时 x − 2 x-2 x−2 和 x x x 是偶数,所以 ( x − 2 ) ⊕ ( x − 1 ) = 1 (x-2) \oplus (x-1) = 1 (x−2)⊕(x−1)=1,然后 x ⊕ 1 = x ⊕ 1 = x + 1 x \oplus 1 = x \oplus 1 = x + 1 x⊕1=x⊕1=x+1。
那么
s ⊕ ( 1 + s ) ⊕ ( 2 + s ) . . . ⊕ ( ( n − 1 ) + s ) ⋅ 2 + b = [ 0 ⊕ 1 ⊕ . . . ⊕ ( s − 1 ) ] ⊕ [ 0 ⊕ 1 ⊕ . . . ⊕ ( s − 1 ) ] ⊕ [ s ⊕ ( 1 + s ) ⊕ ( 2 + s ) . . . ⊕ ( ( n − 1 ) + s ) ] = [ 0 ⊕ 1 ⊕ . . . ⊕ ( s − 1 ) ] ⊕ [ 0 ⊕ 1 ⊕ . . . ⊕ ( s − 1 ) ⊕ s ⊕ ( 1 + s ) . . . ⊕ ( ( n − 1 ) + s ) ] = s u m X o r ( s − 1 ) ⊕ s u m X o r ( s + n − 1 ) \begin{array}{l} s \oplus (1 + s) \oplus (2 + s) ... \oplus ((n-1) + s) \cdot 2 + b \\ = [0 \oplus 1 \oplus ... \oplus (s-1)] \oplus [0 \oplus 1 \oplus ... \oplus (s-1)] \oplus [s \oplus (1 + s) \oplus (2 + s) ... \oplus ((n-1) + s)] \\= [0 \oplus 1 \oplus ... \oplus (s-1)] \oplus [0 \oplus 1 \oplus ... \oplus (s-1) \oplus s \oplus (1 + s) ... \oplus ((n-1) + s)] \\ = sumXor(s-1) \oplus sumXor(s+n-1) \end{array} s⊕(1+s)⊕(2+s)...⊕((n−1)+s)⋅2+b=[0⊕1⊕...⊕(s−1)]⊕[0⊕1⊕...⊕(s−1)]⊕[s⊕(1+s)⊕(2+s)...⊕((n−1)+s)]=[0⊕1⊕...⊕(s−1)]⊕[0⊕1⊕...⊕(s−1)⊕s⊕(1+s)...⊕((n−1)+s)]=sumXor(s−1)⊕sumXor(s+n−1)
这样最后的结果即可表示为 ( s u m X o r ( s − 1 ) ⊕ s u m X o r ( s + n − 1 ) ) × 2 + e (sumXor(s−1)⊕sumXor(s+n−1))×2+e (sumXor(s−1)⊕sumXor(s+n−1))×2+e。
class Solution {
public:int xor_n(int n) {switch (n % 4) {case 0: return n;case 1: return 1;case 2: return n+1;default: return 0;}}int xorOperation(int n, int start) {int e = 1 & n & start, s = start / 2;int ret = xor_n(s-1) ^ xor_n(s + n - 1);return ret * 2 + e;}
};