问题描述
给你两个整数,n 和 start 。
数组 nums 定义为:nums[i] = start + 2*i(下标从 0 开始)且 n == nums.length 。
请返回 nums 中所有元素按位异或(XOR)后得到的结果。
示例1:
输入:n = 5, start = 0
输出:8
解释:数组 nums 为 [0, 2, 4, 6, 8],其中 (0 ^ 2 ^ 4 ^ 6 ^ 8) = 8 。
"^" 为按位异或 XOR 运算符。
示例2:
输入:n = 4, start = 3
输出:8
解释:数组 nums 为 [3, 5, 7, 9],其中 (3 ^ 5 ^ 7 ^ 9) = 8.
示例3:
输入:n = 1, start = 7
输出:7
示例4:
输入:n = 10, start = 5
输出:2
提示:
1 <= n <= 1000
0 <= start <= 1000
n == nums.length
问题思路
思路1:蛮力法
该问题比较简单,通过一次循环,每次求异或即可解决。
实现代码如下,空间复杂度O(1),时间复杂度O(n)。运行时间0 ms。
class Solution {
public int xorOperation(int n, int start) {
int xor = start;
for(int i = 1; i < n; i++){
xor ^= start + 2 * i;
}
return xor;
}
}
思路2:运算性质
使用异或运算的性质,可以进一步降低算法时间复杂度。
首先,题目要求计算 s t a r t ⨁ ( s t a r t + 2 i ) ⨁ ( s t a r t + 4 i ) ⨁ ⋯ ⊕ ( s t a r t + 2 ( n − 1 ) ) start\bigoplus(start+2i)\bigoplus(start+4i)\bigoplus⋯⊕(start+2(n−1)) start⨁(start+2i)⨁(start+4i)⨁⋯⊕(start+2(n−1))
考虑对该公式提取公因数2,由于start的奇偶性无法确定,但其只影响最低位的取值,因此做如下处理:
由于式中各数的奇偶性相同,且 0 ⨁ 0 = 0 , 0 ⨁ 1 = 1 , 1 ⨁ 1 = 0 0 \bigoplus 0 = 0, 0 \bigoplus 1 = 1, 1 \bigoplus 1 = 0 0⨁0=0,0⨁1=1,1⨁1=0
所以当且仅当 start 和 n 均为奇数时,计算结果最低位才为 1 ,其他情况最低位均为 0 。因此可以对 start 除 2 后向下取整,即默认 start 的最低位为0,然后在公式末尾根据 start 和 n 的奇偶性加上 1 即可。得到
( s ⊕ ( s + 1 ) ⊕ ( s + 2 ) ⊕ ⋯ ⊕ ( s + n − 1 ) ) × 2 + e , 其 中 s = ⌊ start 2 ⌋ , e 表 示 运 算 结 果 的 最 低 位 。 (s \oplus (s+1) \oplus (s+2) \oplus \dots \oplus (s+n-1))\times 2 + e,其中 s=\lfloor \frac{\textit{start}}{2}⌋,e 表示运算结果的最低位。 (s⊕(s+1)⊕(s+2)⊕⋯⊕(s+n−1))×2+e,其中s=⌊2start⌋,e表示运算结果的最低位。
这样公式就转化为了连续整数之间的异或运算。
设 s u m X o r ( x ) = 0 ⨁ 1 ⨁ 2 ⨁ ⋯ ⨁ x sumXor(x) = 0 \bigoplus 1 \bigoplus 2 \bigoplus ⋯ \bigoplus x sumXor(x)=0⨁1⨁2⨁⋯⨁x
由于异或运算满足如下性质:
∀ i ∈ Z , 4 i ⨁ ( 4 i + 1 ) ⨁ ( 4 i + 2 ) ⨁ ( 4 i + 3 ) = 0 ∀i∈Z,4i \bigoplus (4i+1) \bigoplus (4i+2) \bigoplus (4i+3) = 0 ∀i∈Z,4i⨁(4i+1)⨁(4i+2)⨁(4i+3)=0
因此
s
u
m
X
o
r
(
x
)
=
{
x
x
=
4
k
,
k
∈
Z
(
x
−
1
)
⨁
x
x
=
4
k
+
1
,
k
∈
Z
(
x
−
2
)
⨁
(
x
−
1
)
⨁
x
x
=
4
k
+
2
,
k
∈
Z
(
x
−
3
)
⨁
(
x
−
2
)
⨁
(
x
−
1
)
⨁
x
x
=
4
k
+
3
,
k
∈
Z
sumXor(x) = \left\{\begin{matrix} x & x = 4k,k \in Z \\ (x-1)\bigoplus x & x = 4k+1,k \in Z \\ (x-2)\bigoplus(x-1)\bigoplus x & x = 4k+2,k \in Z \\ (x-3)\bigoplus(x-2)\bigoplus(x-1)\bigoplus x & x = 4k+3,k \in Z \end{matrix}\right.
sumXor(x)=⎩⎪⎪⎨⎪⎪⎧x(x−1)⨁x(x−2)⨁(x−1)⨁x(x−3)⨁(x−2)⨁(x−1)⨁xx=4k,k∈Zx=4k+1,k∈Zx=4k+2,k∈Zx=4k+3,k∈Z
进一步简化得到
s
u
m
X
o
r
(
x
)
=
{
x
x
=
4
k
,
k
∈
Z
1
x
=
4
k
+
1
,
k
∈
Z
x
+
1
x
=
4
k
+
2
,
k
∈
Z
0
x
=
4
k
+
3
,
k
∈
Z
sumXor(x) = \left\{\begin{matrix} x & x = 4k,k \in Z \\ 1 & x = 4k+1,k \in Z \\ x+1 & x = 4k+2,k \in Z \\ 0 & x = 4k+3,k \in Z \end{matrix}\right.
sumXor(x)=⎩⎪⎪⎨⎪⎪⎧x1x+10x=4k,k∈Zx=4k+1,k∈Zx=4k+2,k∈Zx=4k+3,k∈Z
另:当
a
⨁
b
=
c
a \bigoplus b = c
a⨁b=c有
a
⨁
c
=
b
a \bigoplus c = b
a⨁c=b
因此原式可以进一步化简为 ( s u m X o r ( s − 1 ) ⨁ s u m X o r ( s + n − 1 ) ) × 2 + e (sumXor(s−1) \bigoplus sumXor(s+n−1)) × 2 + e (sumXor(s−1)⨁sumXor(s+n−1))×2+e
实现代码如下,空间复杂度O(1),时间复杂度O(1)。运行时间0 ms。
class Solution {
public int xorOperation(int n, int start) {
int e = (n % 2 == 1 && start % 2 == 1) ? 1 : 0;
return (sumXOR((int) Math.floor(start / 2) - 1) ^ sumXOR((int) Math.floor(start / 2) + n - 1)) * 2 + e;
}
int sumXOR(int x) {
int xx = x % 4;
if (xx == 0) {
return x;
} else if (xx == 1) {
return 1;
} else if (xx == 2) {
return x + 1;
} else {
return 0;
}
}
}