# 有一个正整数数组 arr,现给你一个对应的查询数组 queries,其中 queries[i] = [Li, Ri]。
#
# 对于每个查询 i,请你计算从 Li 到 Ri 的 XOR 值(即 arr[Li] xor arr[Li+1] xor ... xor arr[Ri])作为
# 本次查询的结果。
#
# 并返回一个包含给定查询 queries 所有结果的数组。
#
#
#
# 示例 1:
#
# 输入:arr = [1,3,4,8], queries = [[0,1],[1,2],[0,3],[3,3]]
# 输出:[2,7,14,8]
# 解释:
# 数组中元素的二进制表示形式是:
# 1 = 0001
# 3 = 0011
# 4 = 0100
# 8 = 1000
# 查询的 XOR 值为:
# [0,1] = 1 xor 3 = 2
# [1,2] = 3 xor 4 = 7
# [0,3] = 1 xor 3 xor 4 xor 8 = 14
# [3,3] = 8
#
#
# 示例 2:
#
# 输入:arr = [4,8,2,10], queries = [[2,3],[1,3],[0,0],[0,3]]
# 输出:[8,0,4,4]
#
#
#
#
# 提示:
#
#
# 1 <= arr.length <= 3 * 10^4
# 1 <= arr[i] <= 10^9
# 1 <= queries.length <= 3 * 10^4
# queries[i].length == 2
# 0 <= queries[i][0] <= queries[i][1] < arr.length
#
# Related Topics 位运算
# 👍 69 👎 0
暴力计算,果断超时:
class Solution:
def xorQueries(self, arr: List[int], queries: List[List[int]]) -> List[int]:
ret = []
for q in queries:
ret.append(reduce(xor, arr[q[0] : q[1]+1]))
return ret
用二维动态规划,依然超时:
class Solution:
def xorQueries(self, arr: List[int], queries: List[List[int]]) -> List[int]:
dp = [[0] * len(arr) for _ in range(len(arr))]
for i in range(len(arr)):
dp[i][i] = arr[i]
for i in range(len(arr)):
for j in range(i+1, len(arr)):
dp[i][j] = dp[i][j-1] ^ arr[j]
ret = []
for q in queries:
ret.append(dp[q[0]][q[1]])
return ret
用dict建立重复结果的备忘录,终于勉强通过:
class Solution:
def xorQueries(self, arr: List[int], queries: List[List[int]]) -> List[int]:
ret = []
memo = {}
for q in queries:
if (q[0], q[1]) not in memo.keys():
ans = reduce(xor, arr[q[0]: q[1] + 1])
memo[(q[0], q[1])] = ans
ret.append(memo[(q[0], q[1])])
return ret
执行用时:9072 ms, 在所有 Python3 提交中击败了5.77%的用户
内存消耗:29.4 MB, 在所有 Python3 提交中击败了8.97%的用户
最后参考官方题解,恍然大悟。
其实,动态规划的思路以及很接近了,只不过不需要记录所有dp[i][j]的异或结果,只需记录一维的memo[i](i表示前i个数的异或)的结果即可。因为:
dp[i][j] = memo[i-1] ^ memo[j]
用到了异或操作的结合律,以及相同值异或为0的结论。
最终代码:
class Solution:
def xorQueries(self, arr: List[int], queries: List[List[int]]) -> List[int]:
memo = [0] * (len(arr) + 1)
for i in range(1, len(arr)+1):
memo[i] = memo[i-1] ^ arr[i-1]
ret = []
for i, j in queries:
ret.append(memo[i] ^ memo[j+1])
return ret
执行耗时:424 ms,击败了50.00% 的Python3用户
内存消耗:29.4 MB,击败了14.10% 的Python3用户