You are given an array nums consisting of non-negative integers. You are also given a queries array, where queries[i] = [xi, mi].
The answer to the ith query is the maximum bitwise XOR value of xi and any element of nums that does not exceed mi. In other words, the answer is max(nums[j] XOR xi) for all j such that nums[j] <= mi. If all elements in nums are larger than mi, then the answer is -1.
Return an integer array answer where answer.length == queries.length and answer[i] is the answer to the ith query.
Example 1:
Input: nums = [0,1,2,3,4], queries = [[3,1],[1,3],[5,6]] Output: [3,3,7] Explanation: 1) 0 and 1 are the only two integers not greater than 1. 0 XOR 3 = 3 and 1 XOR 3 = 2. The larger of the two is 3. 2) 1 XOR 2 = 3. 3) 5 XOR 2 = 7.
Example 2:
Input: nums = [5,2,4,6,6,3], queries = [[12,4],[8,1],[6,3]] Output: [15,-1,5]
Constraints:
1 <= nums.length, queries.length <= 105queries[i].length == 20 <= nums[j], xi, mi <= 109Maximum XOR With an Element From Array requires answering multiple queries where each query asks for the maximum nums[i] XOR x such that nums[i] ≤ m. A brute-force scan for every query would be too slow, so the key idea is to process queries efficiently using a bitwise Trie combined with offline sorting.
First, sort the array and process queries in increasing order of their constraint m. As you move through the queries, insert all eligible numbers (nums[i] ≤ m) into a binary Trie built on the bits of the numbers. For each query value x, traverse the Trie greedily, always choosing the opposite bit when possible to maximize the XOR result.
This strategy avoids repeatedly rebuilding structures for each query and ensures that only valid numbers are considered. The Trie enables fast bitwise decisions while the offline ordering keeps insertions efficient.
Time complexity is roughly O((n + q) log n + (n + q) * B), where B is the number of bits (typically 31). Space complexity is O(n * B) for the Trie.
| Approach | Time Complexity | Space Complexity |
|---|---|---|
| Offline Queries + Bitwise Trie | O((n + q) log n + (n + q) * B) | O(n * B) |
take U forward
Use these hints if you're stuck. Try solving on your own first.
In problems involving bitwise operations, we often think on the bits level. In this problem, we can think that to maximize the result of an xor operation, we need to maximize the most significant bit, then the next one, and so on.
If there's some number in the array that is less than m and whose the most significant bit is different than that of x, then xoring with this number maximizes the most significant bit, so I know this bit in the answer is 1.
To check the existence of such numbers and narrow your scope for further bits based on your choice, you can use trie.
You can sort the array and the queries, and maintain the trie such that in each query the trie consists exactly of the valid elements.
Watch expert explanations and walkthroughs
Practice problems asked by these companies to ace your technical interviews.
Explore More ProblemsJot down your thoughts, approach, and key learnings
Processing queries offline allows them to be sorted by the limit m. This makes it easy to incrementally insert eligible numbers into the Trie without repeatedly rebuilding the structure for each query.
Yes, variations of maximum XOR and Trie-based bit manipulation problems are commonly discussed in FAANG-style interviews. They test understanding of bit operations, data structures, and optimization of multiple queries.
A binary Trie (bitwise Trie) is the best data structure for this problem. It stores numbers by their bit representation, allowing efficient traversal to maximize XOR values bit by bit.
The optimal approach uses offline query processing combined with a bitwise Trie. Sort both the array and the queries by the constraint value m, insert valid numbers into the Trie, and greedily maximize XOR for each query.