Maximum XOR for Each Query
Problem
You are given a sorted array nums of n non-negative integers and an integer maximumBit. You want to perform the following query n times:
- Find a non-negative integer
k < 2maximumBitsuch thatnums[0] XOR nums[1] XOR ... XOR nums[nums.length-1] XOR kis maximized.kis the answer to theithquery. - Remove the last element from the current array
nums.
Return an array answer, where answer[i] is the answer to the ith query.
Examples
Example 1:
Input: nums = [0,1,1,3], maximumBit = 2
Output: [0,3,2,3]
Explanation: The queries are answered as follows:
1st query: nums = [0,1,1,3], k = 0 since 0 XOR 1 XOR 1 XOR 3 XOR 0 = 3.
2nd query: nums = [0,1,1], k = 3 since 0 XOR 1 XOR 1 XOR 3 = 3.
3rd query: nums = [0,1], k = 2 since 0 XOR 1 XOR 2 = 3.
4th query: nums = [0], k = 3 since 0 XOR 3 = 3.
Example 2:
Input: nums = [2,3,4,7], maximumBit = 3
Output: [5,2,6,5]
Explanation: The queries are answered as follows:
1st query: nums = [2,3,4,7], k = 5 since 2 XOR 3 XOR 4 XOR 7 XOR 5 = 7.
2nd query: nums = [2,3,4], k = 2 since 2 XOR 3 XOR 4 XOR 2 = 7.
3rd query: nums = [2,3], k = 6 since 2 XOR 3 XOR 6 = 7.
4th query: nums = [2], k = 5 since 2 XOR 5 = 7.
Example 3:
Input: nums = [0,1,2,2,5,7], maximumBit = 3
Output: [4,3,6,4,6,7]
Constraints
0 <= nums[i] < 2^maximumBit
Solution
Method 1 - Calculate xor of whole array
The goal is to find the value of k such that the XOR of all elements in nums and k is maximized for each query. We are given that k < 2^maximumBit, so maximum possible value is achieved with (1 << maximumBit) - 1, meaning all bits within the maximumBit range are set.
It's important to note this constraint as well:
0 <= nums[i] < 2^maximumBit
Why is the maximum always 2^maximumBit - 1?
Given that each element in nums lies within the range [0, 2^maximumBit - 1], after XOR-ing all elements, the resulting value (let's call it numsXor) will also be within this range. Because at maximum, this value will be equal to 2 ^ maxBit - 1.
To maximize the resultant numsXor output, we can xor this value with any number within [0, 2^maximumBit - 1]. The optimal choice is the number which, when XOR-ed with numsXor, yields 2^maximumBit - 1.
For maximumBit = 3, the range is [0, 7]. To achieve the maximum result when XOR-ing number a with another number b, the other number must have opposite bits in each position to ensure all bits are set.
Consider:
maximumBit = 3
numsXor = 0 (000) can be maximized by XOR-ing with 7 to get 7.
0 (000)
^ 7 (111)
----------
7 (111)
numsXor = 1 (001) can be maximized by XOR-ing with 6 to get 7.
1 (001)
^ 6 (110)
----------
7 (111)
numsXor = 2 (010) can be maximized by XOR-ing with 5 to get 7.
2 (010)
^ 5 (101)
----------
7 (111)
numsXor = 3 (011) can be maximized by XOR-ing with 4 to get 7.
3 (011)
^ 4 (100)
----------
7 (111)
numsXor = 4 (100) can be maximized by XOR-ing with 3 to get 7.
4 (100)
^ 3 (011)
----------
7 (111)
and so on.
Following this logic, we can always choose a number to maximize XOR to 2^maximumBit - 1. After computing numsXor for the original nums array, subsequent changes involve removing the last element. We update numsXor by XOR-ing it with the removed element, leveraging the property that XOR-ing an element twice cancels it out. This gives the final answer for each query.
The general idea is:
- Calculate the XOR of all elements in the array
numsinitially, let’s call itnums_xor. - For each query, calculate the best possible value of
kthat, when XORed withnums_xor, provides the maximum value. Since we want the result to be the maximum,kshould benums_xorXOR with all bits set to1within the range2^maximumBit - 1(this is2^maximumBit - 1). - Remove the last element of the array
numsand updatenums_xorby XORing it with the removed element.
Video explanation
Here is the video explaining this method in detail. Please check it out:
<div class="youtube-embed"><iframe src="https://www.youtube.com/embed/0sKfOnJiWZk" frameborder="0" allowfullscreen></iframe></div>
Code
Java
class Solution {
public int[] getMaximumXor(int[] nums, int maximumBit) {
int numsXor = 0;
for (int num : nums) {
numsXor ^= num;
}
int n = nums.length;
int[] ans = new int[n];
int maxK = (1 << maximumBit) - 1;
for (int i = 0; i < n; i++) {
ans[i] = numsXor ^ maxK;
numsXor ^= nums[n - 1 - i];
}
return ans;
}
}
Python
class Solution:
def getMaximumXor(self, nums: List[int], maximumBit: int) -> List[int]:
nums_xor = 0
for num in nums:
nums_xor ^= num
n = len(nums)
ans = [0] * n
max_k = (1 << maximumBit) - 1
for i in range(n):
ans[i] = nums_xor ^ max_k
nums_xor ^= nums[n - 1 - i]
return ans
Complexity
- ⏰ Time complexity:
O(n)wherenis the number of elements innumsbecause we are iterating through the list once and performing constant time operations. - 🧺 Space complexity:
O(1)additional space for calculation, not counting the space of the output array.