3845. Maximum Subarray XOR with Bounded Range
March 10, 2026 · View on GitHub
Description
You are given a non-negative integer array nums and an integer k.
You must select a subarray of nums such that the difference between its maximum and minimum elements is at most k. The value of this subarray is the bitwise XOR of all elements in the subarray.
Return an integer denoting the maximum possible value of the selected subarray.
Example 1:
Input: nums = [5,4,5,6], k = 2
Output: 7
Explanation:
- Select the subarray
[5, 4, 5, 6]. - The difference between its maximum and minimum elements is
6 - 4 = 2 <= k. - The value is
4 XOR 5 XOR 6 = 7.
Example 2:
Input: nums = [5,4,5,6], k = 1
Output: 6
Explanation:
- Select the subarray
[5, 4, 5, 6]. - The difference between its maximum and minimum elements is
6 - 6 = 0 <= k. - The value is 6.
Constraints:
1 <= nums.length <= 4 * 1040 <= nums[i] < 2150 <= k < 215
Solutions
Solution 1
Python3
Java
class Solution {
// Trie node for storing prefix XOR values in binary form
class TrieNode {
TrieNode[] children = new TrieNode[2]; // 0 and 1 branches
int count = 0; // number of prefix values passing through this node
}
TrieNode root = new TrieNode();
// Insert or remove a prefix XOR value from the trie
void updateTrie(int value, int delta) {
TrieNode current = root;
for (int bit = 14; bit >= 0; bit--) {
int currentBit = (value >> bit) & 1;
if (current.children[currentBit] == null) {
current.children[currentBit] = new TrieNode();
}
current = current.children[currentBit];
current.count += delta;
}
}
// Find maximum XOR of given value with any value currently in the trie
int getMaxXor(int value) {
TrieNode current = root;
int maxXor = 0;
for (int bit = 14; bit >= 0; bit--) {
int currentBit = (value >> bit) & 1;
int oppositeBit = 1 - currentBit;
if (current.children[oppositeBit] != null && current.children[oppositeBit].count > 0) {
maxXor |= (1 << bit);
current = current.children[oppositeBit];
} else {
current = current.children[currentBit];
}
}
return maxXor;
}
public int maxXor(int[] nums, int limit) {
int length = nums.length;
// Prefix XOR array
int[] prefixXor = new int[length + 1];
for (int i = 0; i < length; i++) {
prefixXor[i + 1] = prefixXor[i] ^ nums[i];
}
// Monotonic queues to maintain max and min in sliding window
Deque<Integer> maxDeque = new ArrayDeque<>();
Deque<Integer> minDeque = new ArrayDeque<>();
int left = 0;
int result = 0;
updateTrie(prefixXor[0], 1);
for (int right = 0; right < length; right++) {
// Maintain decreasing deque for maximum
while (!maxDeque.isEmpty() && nums[maxDeque.peekLast()] <= nums[right]) {
maxDeque.pollLast();
}
// Maintain increasing deque for minimum
while (!minDeque.isEmpty() && nums[minDeque.peekLast()] >= nums[right]) {
minDeque.pollLast();
}
maxDeque.addLast(right);
minDeque.addLast(right);
// Shrink window if max - min exceeds limit
while (nums[maxDeque.peekFirst()] - nums[minDeque.peekFirst()] > limit) {
if (maxDeque.peekFirst() == left) {
maxDeque.pollFirst();
}
if (minDeque.peekFirst() == left) {
minDeque.pollFirst();
}
updateTrie(prefixXor[left], -1);
left++;
}
result = Math.max(result, getMaxXor(prefixXor[right + 1]));
updateTrie(prefixXor[right + 1], 1);
}
return result;
}
}
C++
Go