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 <= 105
queries[i].length == 2
0 <= nums[j], xi, mi <= 109
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method tries every possible number in the list against our input number to find the best pairing. We will try every single combination without any shortcuts to ensure we don't miss the maximum XOR result. This involves a direct, exhaustive comparison.
Here's how the algorithm would work step-by-step:
def maximum_xor_with_element_from_array_brute_force(numbers, queries):
results = []
for query in queries:
number = query[0]
maximum_limit = query[1]
maximum_xor_result = -1
for list_number in numbers:
# Ensure that the number from the list is within the limit.
if list_number <= maximum_limit:
current_xor_result = number ^ list_number
# Compare current XOR to existing XOR to keep track of maximum
if current_xor_result > maximum_xor_result:
maximum_xor_result = current_xor_result
results.append(maximum_xor_result)
return results
To efficiently find the maximum XOR value, we'll organize our numbers in a special tree-like structure called a Trie. This structure lets us quickly find the number that, when XORed with our target, gives us the highest possible result by walking down the Trie making greedy decisions at each step.
Here's how the algorithm would work step-by-step:
class TrieNode:
def __init__(self):
self.children = [None] * 2
class Trie:
def __init__(self):
self.root = TrieNode()
def insert(self, number):
current_node = self.root
for i in range(31, -1, -1):
bit = (number >> i) & 1
if not current_node.children[bit]:
current_node.children[bit] = TrieNode()
current_node = current_node.children[bit]
def find_max_xor(self, number):
current_node = self.root
max_xor = 0
for i in range(31, -1, -1):
bit = (number >> i) & 1
opposite_bit = 1 - bit
if current_node.children[opposite_bit]:
max_xor |= (1 << i)
current_node = current_node.children[opposite_bit]
else:
current_node = current_node.children[bit]
return max_xor
def max_xor_with_element(numbers, queries):
numbers_with_limits = []
for index, (value, limit) in enumerate(queries):
numbers_with_limits.append((value, limit, index))
numbers.sort()
numbers_with_limits.sort(key=lambda x: x[1])
trie = Trie()
maximum_xors = [0] * len(queries)
number_index = 0
for value, limit, index in numbers_with_limits:
# Insert elements into Trie that are <= current limit
while number_index < len(numbers) and numbers[number_index] <= limit:
trie.insert(numbers[number_index])
number_index += 1
# If the trie is empty, then we can't find any valid number
if number_index == 0 and numbers[0] > limit:
maximum_xors[index] = -1
continue
# Find maximum XOR for current value
maximum_xors[index] = trie.find_max_xor(value)
return maximum_xors
Case | How to Handle |
---|---|
Empty nums array | Return an empty list since no XOR operations are possible. |
Empty queries array | Return an empty list as there are no queries to process. |
nums array with one element | Iterate through queries and compare single element with limit for valid XOR, or return -1 if exceeds limit |
Large nums array (scalability) | Trie-based solution provides logarithmic search, thus scaling effectively. |
Large queries array (scalability) | Process each query independently, benefiting from the Trie's logarithmic search time. |
nums array contains very large numbers (close to integer limit) | Trie should handle full integer bit representation to correctly compute XOR. |
Numbers exceeding the bit length accounted for in the trie | Ensure the trie is constructed with enough bits to accommodate all numbers in the input. |
Queries with small limits (close to zero) | The solution should correctly filter numbers that exceed the limit and return -1 when no valid XOR can be found. |