题目描述
给你一个由 n
个整数组成的数组 nums
,以及一个大小为 q
的二维整数数组 queries
,其中 queries[i] = [li, ri]
。
对于每一个查询,你需要找出 nums[li..ri]
中任意 子数组 的 最大异或值。
数组的异或值 需要对数组 a
反复执行以下操作,直到只剩一个元素,剩下的那个元素就是 异或值:
- 对于除最后一个下标以外的所有下标
i
,同时将 a[i]
替换为 a[i] XOR a[i + 1]
。
- 移除数组的最后一个元素。
返回一个大小为 q
的数组 answer
,其中 answer[i]
表示查询 i
的答案。
示例 1:
输入: nums = [2,8,4,32,16,1], queries = [[0,2],[1,4],[0,5]]
输出: [12,60,60]
解释:
在第一个查询中,nums[0..2]
的子数组分别是 [2]
, [8]
, [4]
, [2, 8]
, [8, 4]
, 和 [2, 8, 4]
,它们的异或值分别为 2, 8, 4, 10, 12, 和 6。查询的答案是 12,所有异或值中的最大值。
在第二个查询中,nums[1..4]
的子数组中最大的异或值是子数组 nums[1..4]
的异或值,为 60。
在第三个查询中,nums[0..5]
的子数组中最大的异或值是子数组 nums[1..4]
的异或值,为 60。
示例 2:
输入: nums = [0,7,3,2,8,5,1], queries = [[0,3],[1,5],[2,4],[2,6],[5,6]]
输出: [7,14,11,14,5]
解释:
下标 |
nums[li..ri] |
最大异或值子数组 |
子数组最大异或值 |
0 |
[0, 7, 3, 2] |
[7] |
7 |
1 |
[7, 3, 2, 8, 5] |
[7, 3, 2, 8] |
14 |
2 |
[3, 2, 8] |
[3, 2, 8] |
11 |
3 |
[3, 2, 8, 5, 1] |
[2, 8, 5, 1] |
14 |
4 |
[5, 1] |
[5] |
5 |
提示:
1 <= n == nums.length <= 2000
0 <= nums[i] <= 231 - 1
1 <= q == queries.length <= 105
queries[i].length == 2
queries[i] = [li, ri]
0 <= li <= ri <= n - 1
解法
方法一:动态规划
我们定义 $f[i][j]$ 表示 $\textit{nums}[i..j]$ 的异或值,那么根据题目描述,我们可以得到状态转移方程:
$$
f[i][j] = f[i][j-1] \oplus f[i+1][j]
$$
其中 $\oplus$ 表示异或运算。
我们再定义 $g[i][j]$ 表示 $f[i][j]$ 的最大值,那么状态转移方程为:
$$
g[i][j] = \max(f[i][j], g[i][j-1], g[i+1][j])
$$
最后,我们遍历查询数组,对于每个查询 $[l, r]$,将 $g[l][r]$ 加入答案数组即可。
时间复杂度 $O(n^2 + m)$,空间复杂度 $O(n^2)$。其中 $n$ 和 $m$ 分别为数组 $\textit{nums}$ 和 $\textit{queries}$ 的长度。
1
2
3
4
5
6
7
8
9
10
11
12
13 | class Solution:
def maximumSubarrayXor(
self, nums: List[int], queries: List[List[int]]
) -> List[int]:
n = len(nums)
f = [[0] * n for _ in range(n)]
g = [[0] * n for _ in range(n)]
for i in range(n - 1, -1, -1):
f[i][i] = g[i][i] = nums[i]
for j in range(i + 1, n):
f[i][j] = f[i][j - 1] ^ f[i + 1][j]
g[i][j] = max(f[i][j], g[i][j - 1], g[i + 1][j])
return [g[l][r] for l, r in queries]
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 | class Solution {
public int[] maximumSubarrayXor(int[] nums, int[][] queries) {
int n = nums.length;
int[][] f = new int[n][n];
int[][] g = new int[n][n];
for (int i = n - 1; i >= 0; --i) {
f[i][i] = nums[i];
g[i][i] = nums[i];
for (int j = i + 1; j < n; ++j) {
f[i][j] = f[i][j - 1] ^ f[i + 1][j];
g[i][j] = Math.max(f[i][j], Math.max(g[i][j - 1], g[i + 1][j]));
}
}
int m = queries.length;
int[] ans = new int[m];
for (int i = 0; i < m; ++i) {
int l = queries[i][0], r = queries[i][1];
ans[i] = g[l][r];
}
return ans;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 | class Solution {
public:
vector<int> maximumSubarrayXor(vector<int>& nums, vector<vector<int>>& queries) {
int n = nums.size();
vector<vector<int>> f(n, vector<int>(n));
vector<vector<int>> g(n, vector<int>(n));
for (int i = n - 1; i >= 0; --i) {
f[i][i] = nums[i];
g[i][i] = nums[i];
for (int j = i + 1; j < n; ++j) {
f[i][j] = f[i][j - 1] ^ f[i + 1][j];
g[i][j] = max({f[i][j], g[i][j - 1], g[i + 1][j]});
}
}
vector<int> ans;
for (const auto& q : queries) {
int l = q[0], r = q[1];
ans.push_back(g[l][r]);
}
return ans;
}
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 | func maximumSubarrayXor(nums []int, queries [][]int) (ans []int) {
n := len(nums)
f := make([][]int, n)
g := make([][]int, n)
for i := 0; i < n; i++ {
f[i] = make([]int, n)
g[i] = make([]int, n)
}
for i := n - 1; i >= 0; i-- {
f[i][i] = nums[i]
g[i][i] = nums[i]
for j := i + 1; j < n; j++ {
f[i][j] = f[i][j-1] ^ f[i+1][j]
g[i][j] = max(f[i][j], max(g[i][j-1], g[i+1][j]))
}
}
for _, q := range queries {
l, r := q[0], q[1]
ans = append(ans, g[l][r])
}
return
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | function maximumSubarrayXor(nums: number[], queries: number[][]): number[] {
const n = nums.length;
const f: number[][] = Array.from({ length: n }, () => Array(n).fill(0));
const g: number[][] = Array.from({ length: n }, () => Array(n).fill(0));
for (let i = n - 1; i >= 0; i--) {
f[i][i] = nums[i];
g[i][i] = nums[i];
for (let j = i + 1; j < n; j++) {
f[i][j] = f[i][j - 1] ^ f[i + 1][j];
g[i][j] = Math.max(f[i][j], Math.max(g[i][j - 1], g[i + 1][j]));
}
}
return queries.map(([l, r]) => g[l][r]);
}
|