Skip to content

Commit 7639df8

Browse files
feat: add java solution for lc No.3845 (#5036)
1 parent 9983df7 commit 7639df8

3 files changed

Lines changed: 294 additions & 2 deletions

File tree

solution/3800-3899/3845.Maximum Subarray XOR with Bounded Range/README.md

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,104 @@ tags:
9696
#### Java
9797

9898
```java
99-
99+
class Solution {
100+
101+
// Trie node for storing prefix XOR values in binary form
102+
class TrieNode {
103+
TrieNode[] children = new TrieNode[2]; // 0 and 1 branches
104+
int count = 0; // number of prefix values passing through this node
105+
}
106+
107+
TrieNode root = new TrieNode();
108+
109+
// Insert or remove a prefix XOR value from the trie
110+
void updateTrie(int value, int delta) {
111+
TrieNode current = root;
112+
for (int bit = 14; bit >= 0; bit--) {
113+
int currentBit = (value >> bit) & 1;
114+
if (current.children[currentBit] == null) {
115+
current.children[currentBit] = new TrieNode();
116+
}
117+
current = current.children[currentBit];
118+
current.count += delta;
119+
}
120+
}
121+
122+
// Find maximum XOR of given value with any value currently in the trie
123+
int getMaxXor(int value) {
124+
TrieNode current = root;
125+
int maxXor = 0;
126+
127+
for (int bit = 14; bit >= 0; bit--) {
128+
int currentBit = (value >> bit) & 1;
129+
int oppositeBit = 1 - currentBit;
130+
131+
if (current.children[oppositeBit] != null && current.children[oppositeBit].count > 0) {
132+
maxXor |= (1 << bit);
133+
current = current.children[oppositeBit];
134+
} else {
135+
current = current.children[currentBit];
136+
}
137+
}
138+
139+
return maxXor;
140+
}
141+
142+
public int maxXor(int[] nums, int limit) {
143+
int length = nums.length;
144+
145+
// Prefix XOR array
146+
int[] prefixXor = new int[length + 1];
147+
for (int i = 0; i < length; i++) {
148+
prefixXor[i + 1] = prefixXor[i] ^ nums[i];
149+
}
150+
151+
// Monotonic queues to maintain max and min in sliding window
152+
Deque<Integer> maxDeque = new ArrayDeque<>();
153+
Deque<Integer> minDeque = new ArrayDeque<>();
154+
155+
int left = 0;
156+
int result = 0;
157+
158+
updateTrie(prefixXor[0], 1);
159+
160+
for (int right = 0; right < length; right++) {
161+
162+
// Maintain decreasing deque for maximum
163+
while (!maxDeque.isEmpty() && nums[maxDeque.peekLast()] <= nums[right]) {
164+
maxDeque.pollLast();
165+
}
166+
167+
// Maintain increasing deque for minimum
168+
while (!minDeque.isEmpty() && nums[minDeque.peekLast()] >= nums[right]) {
169+
minDeque.pollLast();
170+
}
171+
172+
maxDeque.addLast(right);
173+
minDeque.addLast(right);
174+
175+
// Shrink window if max - min exceeds limit
176+
while (nums[maxDeque.peekFirst()] - nums[minDeque.peekFirst()] > limit) {
177+
178+
if (maxDeque.peekFirst() == left) {
179+
maxDeque.pollFirst();
180+
}
181+
182+
if (minDeque.peekFirst() == left) {
183+
minDeque.pollFirst();
184+
}
185+
186+
updateTrie(prefixXor[left], -1);
187+
left++;
188+
}
189+
190+
result = Math.max(result, getMaxXor(prefixXor[right + 1]));
191+
updateTrie(prefixXor[right + 1], 1);
192+
}
193+
194+
return result;
195+
}
196+
}
100197
```
101198

102199
#### C++

solution/3800-3899/3845.Maximum Subarray XOR with Bounded Range/README_EN.md

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,104 @@ tags:
9191
#### Java
9292

9393
```java
94-
94+
class Solution {
95+
96+
// Trie node for storing prefix XOR values in binary form
97+
class TrieNode {
98+
TrieNode[] children = new TrieNode[2]; // 0 and 1 branches
99+
int count = 0; // number of prefix values passing through this node
100+
}
101+
102+
TrieNode root = new TrieNode();
103+
104+
// Insert or remove a prefix XOR value from the trie
105+
void updateTrie(int value, int delta) {
106+
TrieNode current = root;
107+
for (int bit = 14; bit >= 0; bit--) {
108+
int currentBit = (value >> bit) & 1;
109+
if (current.children[currentBit] == null) {
110+
current.children[currentBit] = new TrieNode();
111+
}
112+
current = current.children[currentBit];
113+
current.count += delta;
114+
}
115+
}
116+
117+
// Find maximum XOR of given value with any value currently in the trie
118+
int getMaxXor(int value) {
119+
TrieNode current = root;
120+
int maxXor = 0;
121+
122+
for (int bit = 14; bit >= 0; bit--) {
123+
int currentBit = (value >> bit) & 1;
124+
int oppositeBit = 1 - currentBit;
125+
126+
if (current.children[oppositeBit] != null && current.children[oppositeBit].count > 0) {
127+
maxXor |= (1 << bit);
128+
current = current.children[oppositeBit];
129+
} else {
130+
current = current.children[currentBit];
131+
}
132+
}
133+
134+
return maxXor;
135+
}
136+
137+
public int maxXor(int[] nums, int limit) {
138+
int length = nums.length;
139+
140+
// Prefix XOR array
141+
int[] prefixXor = new int[length + 1];
142+
for (int i = 0; i < length; i++) {
143+
prefixXor[i + 1] = prefixXor[i] ^ nums[i];
144+
}
145+
146+
// Monotonic queues to maintain max and min in sliding window
147+
Deque<Integer> maxDeque = new ArrayDeque<>();
148+
Deque<Integer> minDeque = new ArrayDeque<>();
149+
150+
int left = 0;
151+
int result = 0;
152+
153+
updateTrie(prefixXor[0], 1);
154+
155+
for (int right = 0; right < length; right++) {
156+
157+
// Maintain decreasing deque for maximum
158+
while (!maxDeque.isEmpty() && nums[maxDeque.peekLast()] <= nums[right]) {
159+
maxDeque.pollLast();
160+
}
161+
162+
// Maintain increasing deque for minimum
163+
while (!minDeque.isEmpty() && nums[minDeque.peekLast()] >= nums[right]) {
164+
minDeque.pollLast();
165+
}
166+
167+
maxDeque.addLast(right);
168+
minDeque.addLast(right);
169+
170+
// Shrink window if max - min exceeds limit
171+
while (nums[maxDeque.peekFirst()] - nums[minDeque.peekFirst()] > limit) {
172+
173+
if (maxDeque.peekFirst() == left) {
174+
maxDeque.pollFirst();
175+
}
176+
177+
if (minDeque.peekFirst() == left) {
178+
minDeque.pollFirst();
179+
}
180+
181+
updateTrie(prefixXor[left], -1);
182+
left++;
183+
}
184+
185+
result = Math.max(result, getMaxXor(prefixXor[right + 1]));
186+
updateTrie(prefixXor[right + 1], 1);
187+
}
188+
189+
return result;
190+
}
191+
}
95192
```
96193

97194
#### C++
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
class Solution {
2+
3+
// Trie node for storing prefix XOR values in binary form
4+
class TrieNode {
5+
TrieNode[] children = new TrieNode[2]; // 0 and 1 branches
6+
int count = 0; // number of prefix values passing through this node
7+
}
8+
9+
TrieNode root = new TrieNode();
10+
11+
// Insert or remove a prefix XOR value from the trie
12+
void updateTrie(int value, int delta) {
13+
TrieNode current = root;
14+
for (int bit = 14; bit >= 0; bit--) {
15+
int currentBit = (value >> bit) & 1;
16+
if (current.children[currentBit] == null) {
17+
current.children[currentBit] = new TrieNode();
18+
}
19+
current = current.children[currentBit];
20+
current.count += delta;
21+
}
22+
}
23+
24+
// Find maximum XOR of given value with any value currently in the trie
25+
int getMaxXor(int value) {
26+
TrieNode current = root;
27+
int maxXor = 0;
28+
29+
for (int bit = 14; bit >= 0; bit--) {
30+
int currentBit = (value >> bit) & 1;
31+
int oppositeBit = 1 - currentBit;
32+
33+
if (current.children[oppositeBit] != null && current.children[oppositeBit].count > 0) {
34+
maxXor |= (1 << bit);
35+
current = current.children[oppositeBit];
36+
} else {
37+
current = current.children[currentBit];
38+
}
39+
}
40+
41+
return maxXor;
42+
}
43+
44+
public int maxXor(int[] nums, int limit) {
45+
int length = nums.length;
46+
47+
// Prefix XOR array
48+
int[] prefixXor = new int[length + 1];
49+
for (int i = 0; i < length; i++) {
50+
prefixXor[i + 1] = prefixXor[i] ^ nums[i];
51+
}
52+
53+
// Monotonic queues to maintain max and min in sliding window
54+
Deque<Integer> maxDeque = new ArrayDeque<>();
55+
Deque<Integer> minDeque = new ArrayDeque<>();
56+
57+
int left = 0;
58+
int result = 0;
59+
60+
updateTrie(prefixXor[0], 1);
61+
62+
for (int right = 0; right < length; right++) {
63+
64+
// Maintain decreasing deque for maximum
65+
while (!maxDeque.isEmpty() && nums[maxDeque.peekLast()] <= nums[right]) {
66+
maxDeque.pollLast();
67+
}
68+
69+
// Maintain increasing deque for minimum
70+
while (!minDeque.isEmpty() && nums[minDeque.peekLast()] >= nums[right]) {
71+
minDeque.pollLast();
72+
}
73+
74+
maxDeque.addLast(right);
75+
minDeque.addLast(right);
76+
77+
// Shrink window if max - min exceeds limit
78+
while (nums[maxDeque.peekFirst()] - nums[minDeque.peekFirst()] > limit) {
79+
80+
if (maxDeque.peekFirst() == left) {
81+
maxDeque.pollFirst();
82+
}
83+
84+
if (minDeque.peekFirst() == left) {
85+
minDeque.pollFirst();
86+
}
87+
88+
updateTrie(prefixXor[left], -1);
89+
left++;
90+
}
91+
92+
result = Math.max(result, getMaxXor(prefixXor[right + 1]));
93+
updateTrie(prefixXor[right + 1], 1);
94+
}
95+
96+
return result;
97+
}
98+
}

0 commit comments

Comments
 (0)