Skip to content

Commit e1541b3

Browse files
authored
feat: add solutions to lc problem: No.3599 (#4536)
No.3599.Partition Array to Minimize XOR
1 parent 4ae8f79 commit e1541b3

File tree

7 files changed

+383
-8
lines changed

7 files changed

+383
-8
lines changed

solution/3500-3599/3599.Partition Array to Minimize XOR/README.md

Lines changed: 134 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,32 +98,162 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3500-3599/3599.Pa
9898

9999
<!-- solution:start -->
100100

101-
### 方法一
101+
### 方法一:动态规划
102+
103+
我们定义 $f[i][j]$ 表示将前 $i$ 个元素划分成 $j$ 个子数组的最大 XOR 的最小值。初始时 $f[0][0] = 0$,其余 $f[i][j] = +\infty$。
104+
105+
为了快速计算子数组的 XOR,我们可以使用前缀 XOR 数组 $g$,其中 $g[i]$ 表示前 $i$ 个元素的 XOR 值,那么对于子数组 $[h + 1...i]$(下标从 $1$ 开始),其 XOR 值为 $g[i] \oplus g[h]$。
106+
107+
接下来,我们在 $[1, n]$ 的范围内遍历 $i$,在 $[1, \min(i, k)]$ 的范围内遍历 $j$,并在 $[j - 1, i - 1]$ 的范围内遍历 $h$,其中 $h$ 表示上一个子数组的结束位置(下标从 $1$ 开始)。我们可以通过以下状态转移方程来更新 $f[i][j]$:
108+
109+
$$
110+
f[i][j] = \min_{h \in [j - 1, i - 1]} \max(f[h][j - 1], g[i] \oplus g[h])
111+
$$
112+
113+
最后,我们返回 $f[n][k]$,即将整个数组划分成 $k$ 个子数组的最大 XOR 的最小值。
114+
115+
时间复杂度 $O(n^2 \times k)$,空间复杂度 $O(n \times k)$,其中 $n$ 是数组的长度。
102116

103117
<!-- tabs:start -->
104118

105119
#### Python3
106120

107121
```python
108-
122+
min = lambda a, b: a if a < b else b
123+
max = lambda a, b: a if a > b else b
124+
125+
126+
class Solution:
127+
def minXor(self, nums: List[int], k: int) -> int:
128+
n = len(nums)
129+
g = [0] * (n + 1)
130+
for i, x in enumerate(nums, 1):
131+
g[i] = g[i - 1] ^ x
132+
133+
f = [[inf] * (k + 1) for _ in range(n + 1)]
134+
f[0][0] = 0
135+
for i in range(1, n + 1):
136+
for j in range(1, min(i, k) + 1):
137+
for h in range(j - 1, i):
138+
f[i][j] = min(f[i][j], max(f[h][j - 1], g[i] ^ g[h]))
139+
return f[n][k]
109140
```
110141

111142
#### Java
112143

113144
```java
114-
145+
class Solution {
146+
public int minXor(int[] nums, int k) {
147+
int n = nums.length;
148+
int[] g = new int[n + 1];
149+
for (int i = 1; i <= n; ++i) {
150+
g[i] = g[i - 1] ^ nums[i - 1];
151+
}
152+
153+
int[][] f = new int[n + 1][k + 1];
154+
for (int i = 0; i <= n; ++i) {
155+
Arrays.fill(f[i], Integer.MAX_VALUE);
156+
}
157+
f[0][0] = 0;
158+
159+
for (int i = 1; i <= n; ++i) {
160+
for (int j = 1; j <= Math.min(i, k); ++j) {
161+
for (int h = j - 1; h < i; ++h) {
162+
f[i][j] = Math.min(f[i][j], Math.max(f[h][j - 1], g[i] ^ g[h]));
163+
}
164+
}
165+
}
166+
167+
return f[n][k];
168+
}
169+
}
115170
```
116171

117172
#### C++
118173

119174
```cpp
120-
175+
class Solution {
176+
public:
177+
int minXor(vector<int>& nums, int k) {
178+
int n = nums.size();
179+
vector<int> g(n + 1);
180+
for (int i = 1; i <= n; ++i) {
181+
g[i] = g[i - 1] ^ nums[i - 1];
182+
}
183+
184+
const int inf = numeric_limits<int>::max();
185+
vector f(n + 1, vector(k + 1, inf));
186+
f[0][0] = 0;
187+
188+
for (int i = 1; i <= n; ++i) {
189+
for (int j = 1; j <= min(i, k); ++j) {
190+
for (int h = j - 1; h < i; ++h) {
191+
f[i][j] = min(f[i][j], max(f[h][j - 1], g[i] ^ g[h]));
192+
}
193+
}
194+
}
195+
196+
return f[n][k];
197+
}
198+
};
121199
```
122200

123201
#### Go
124202

125203
```go
204+
func minXor(nums []int, k int) int {
205+
n := len(nums)
206+
g := make([]int, n+1)
207+
for i := 1; i <= n; i++ {
208+
g[i] = g[i-1] ^ nums[i-1]
209+
}
210+
211+
const inf = math.MaxInt32
212+
f := make([][]int, n+1)
213+
for i := range f {
214+
f[i] = make([]int, k+1)
215+
for j := range f[i] {
216+
f[i][j] = inf
217+
}
218+
}
219+
f[0][0] = 0
220+
221+
for i := 1; i <= n; i++ {
222+
for j := 1; j <= min(i, k); j++ {
223+
for h := j - 1; h < i; h++ {
224+
f[i][j] = min(f[i][j], max(f[h][j-1], g[i]^g[h]))
225+
}
226+
}
227+
}
228+
229+
return f[n][k]
230+
}
231+
```
126232

233+
#### TypeScript
234+
235+
```ts
236+
function minXor(nums: number[], k: number): number {
237+
const n = nums.length;
238+
const g: number[] = Array(n + 1).fill(0);
239+
for (let i = 1; i <= n; ++i) {
240+
g[i] = g[i - 1] ^ nums[i - 1];
241+
}
242+
243+
const inf = Number.MAX_SAFE_INTEGER;
244+
const f: number[][] = Array.from({ length: n + 1 }, () => Array(k + 1).fill(inf));
245+
f[0][0] = 0;
246+
247+
for (let i = 1; i <= n; ++i) {
248+
for (let j = 1; j <= Math.min(i, k); ++j) {
249+
for (let h = j - 1; h < i; ++h) {
250+
f[i][j] = Math.min(f[i][j], Math.max(f[h][j - 1], g[i] ^ g[h]));
251+
}
252+
}
253+
}
254+
255+
return f[n][k];
256+
}
127257
```
128258

129259
<!-- tabs:end -->

solution/3500-3599/3599.Partition Array to Minimize XOR/README_EN.md

Lines changed: 134 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,32 +95,162 @@ A <strong>subarray</strong> is a contiguous <b>non-empty</b> sequence of element
9595

9696
<!-- solution:start -->
9797

98-
### Solution 1
98+
### Solution 1: Dynamic Programming
99+
100+
We define $f[i][j]$ as the minimum possible value of the maximum XOR among all ways to partition the first $i$ elements into $j$ subarrays. Initially, set $f[0][0] = 0$, and all other $f[i][j] = +\infty$.
101+
102+
To quickly compute the XOR of a subarray, we can use a prefix XOR array $g$, where $g[i]$ represents the XOR of the first $i$ elements. For the subarray $[h + 1...i]$ (with indices starting from $1$), its XOR value is $g[i] \oplus g[h]$.
103+
104+
Next, we iterate $i$ from $1$ to $n$, $j$ from $1$ to $\min(i, k)$, and $h$ from $j - 1$ to $i - 1$, where $h$ represents the end position of the previous subarray (indices starting from $1$). We update $f[i][j]$ using the following state transition equation:
105+
106+
$$
107+
f[i][j] = \min_{h \in [j - 1, i - 1]} \max(f[h][j - 1], g[i] \oplus g[h])
108+
$$
109+
110+
Finally, we return $f[n][k]$, which is the minimum possible value of the maximum XOR when partitioning the entire array into $k$ subarrays.
111+
112+
The time complexity is $O(n^2 \times k)$, and the space complexity is $O(n \times k)$, where $n$ is the length of the array.
99113

100114
<!-- tabs:start -->
101115

102116
#### Python3
103117

104118
```python
105-
119+
min = lambda a, b: a if a < b else b
120+
max = lambda a, b: a if a > b else b
121+
122+
123+
class Solution:
124+
def minXor(self, nums: List[int], k: int) -> int:
125+
n = len(nums)
126+
g = [0] * (n + 1)
127+
for i, x in enumerate(nums, 1):
128+
g[i] = g[i - 1] ^ x
129+
130+
f = [[inf] * (k + 1) for _ in range(n + 1)]
131+
f[0][0] = 0
132+
for i in range(1, n + 1):
133+
for j in range(1, min(i, k) + 1):
134+
for h in range(j - 1, i):
135+
f[i][j] = min(f[i][j], max(f[h][j - 1], g[i] ^ g[h]))
136+
return f[n][k]
106137
```
107138

108139
#### Java
109140

110141
```java
111-
142+
class Solution {
143+
public int minXor(int[] nums, int k) {
144+
int n = nums.length;
145+
int[] g = new int[n + 1];
146+
for (int i = 1; i <= n; ++i) {
147+
g[i] = g[i - 1] ^ nums[i - 1];
148+
}
149+
150+
int[][] f = new int[n + 1][k + 1];
151+
for (int i = 0; i <= n; ++i) {
152+
Arrays.fill(f[i], Integer.MAX_VALUE);
153+
}
154+
f[0][0] = 0;
155+
156+
for (int i = 1; i <= n; ++i) {
157+
for (int j = 1; j <= Math.min(i, k); ++j) {
158+
for (int h = j - 1; h < i; ++h) {
159+
f[i][j] = Math.min(f[i][j], Math.max(f[h][j - 1], g[i] ^ g[h]));
160+
}
161+
}
162+
}
163+
164+
return f[n][k];
165+
}
166+
}
112167
```
113168

114169
#### C++
115170

116171
```cpp
117-
172+
class Solution {
173+
public:
174+
int minXor(vector<int>& nums, int k) {
175+
int n = nums.size();
176+
vector<int> g(n + 1);
177+
for (int i = 1; i <= n; ++i) {
178+
g[i] = g[i - 1] ^ nums[i - 1];
179+
}
180+
181+
const int inf = numeric_limits<int>::max();
182+
vector f(n + 1, vector(k + 1, inf));
183+
f[0][0] = 0;
184+
185+
for (int i = 1; i <= n; ++i) {
186+
for (int j = 1; j <= min(i, k); ++j) {
187+
for (int h = j - 1; h < i; ++h) {
188+
f[i][j] = min(f[i][j], max(f[h][j - 1], g[i] ^ g[h]));
189+
}
190+
}
191+
}
192+
193+
return f[n][k];
194+
}
195+
};
118196
```
119197

120198
#### Go
121199

122200
```go
201+
func minXor(nums []int, k int) int {
202+
n := len(nums)
203+
g := make([]int, n+1)
204+
for i := 1; i <= n; i++ {
205+
g[i] = g[i-1] ^ nums[i-1]
206+
}
207+
208+
const inf = math.MaxInt32
209+
f := make([][]int, n+1)
210+
for i := range f {
211+
f[i] = make([]int, k+1)
212+
for j := range f[i] {
213+
f[i][j] = inf
214+
}
215+
}
216+
f[0][0] = 0
217+
218+
for i := 1; i <= n; i++ {
219+
for j := 1; j <= min(i, k); j++ {
220+
for h := j - 1; h < i; h++ {
221+
f[i][j] = min(f[i][j], max(f[h][j-1], g[i]^g[h]))
222+
}
223+
}
224+
}
225+
226+
return f[n][k]
227+
}
228+
```
123229

230+
#### TypeScript
231+
232+
```ts
233+
function minXor(nums: number[], k: number): number {
234+
const n = nums.length;
235+
const g: number[] = Array(n + 1).fill(0);
236+
for (let i = 1; i <= n; ++i) {
237+
g[i] = g[i - 1] ^ nums[i - 1];
238+
}
239+
240+
const inf = Number.MAX_SAFE_INTEGER;
241+
const f: number[][] = Array.from({ length: n + 1 }, () => Array(k + 1).fill(inf));
242+
f[0][0] = 0;
243+
244+
for (let i = 1; i <= n; ++i) {
245+
for (let j = 1; j <= Math.min(i, k); ++j) {
246+
for (let h = j - 1; h < i; ++h) {
247+
f[i][j] = Math.min(f[i][j], Math.max(f[h][j - 1], g[i] ^ g[h]));
248+
}
249+
}
250+
}
251+
252+
return f[n][k];
253+
}
124254
```
125255

126256
<!-- tabs:end -->
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class Solution {
2+
public:
3+
int minXor(vector<int>& nums, int k) {
4+
int n = nums.size();
5+
vector<int> g(n + 1);
6+
for (int i = 1; i <= n; ++i) {
7+
g[i] = g[i - 1] ^ nums[i - 1];
8+
}
9+
10+
const int inf = numeric_limits<int>::max();
11+
vector f(n + 1, vector(k + 1, inf));
12+
f[0][0] = 0;
13+
14+
for (int i = 1; i <= n; ++i) {
15+
for (int j = 1; j <= min(i, k); ++j) {
16+
for (int h = j - 1; h < i; ++h) {
17+
f[i][j] = min(f[i][j], max(f[h][j - 1], g[i] ^ g[h]));
18+
}
19+
}
20+
}
21+
22+
return f[n][k];
23+
}
24+
};
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
func minXor(nums []int, k int) int {
2+
n := len(nums)
3+
g := make([]int, n+1)
4+
for i := 1; i <= n; i++ {
5+
g[i] = g[i-1] ^ nums[i-1]
6+
}
7+
8+
const inf = math.MaxInt32
9+
f := make([][]int, n+1)
10+
for i := range f {
11+
f[i] = make([]int, k+1)
12+
for j := range f[i] {
13+
f[i][j] = inf
14+
}
15+
}
16+
f[0][0] = 0
17+
18+
for i := 1; i <= n; i++ {
19+
for j := 1; j <= min(i, k); j++ {
20+
for h := j - 1; h < i; h++ {
21+
f[i][j] = min(f[i][j], max(f[h][j-1], g[i]^g[h]))
22+
}
23+
}
24+
}
25+
26+
return f[n][k]
27+
}

0 commit comments

Comments
 (0)