1707. Maximum XOR With an Element From Array
Description
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
Solutions
Solution: Trie + Bit Manipulation
- Time complexity: O(mlogm+nlogn+(m+n)*log(Max(nums[i])))
- Space complexity: O(m*log(Max(nums[i]))+n)
JavaScript
js
/**
* @param {number[]} nums
* @param {number[][]} queries
* @return {number[]}
*/
const maximizeXor = function (nums, queries) {
const m = nums.length;
const n = queries.length;
const indexedQueries = queries.map((query, index) => {
const [xor, max] = query;
return { xor, max, index };
});
nums.sort((a, b) => a - b);
indexedQueries.sort((a, b) => a.max - b.max);
const maxNum = Math.max(nums[m - 1], indexedQueries[n - 1].max);
const trie = new BitTrie(maxNum);
const result = Array.from({ length: n }, () => -1);
let index = 0;
for (const query of indexedQueries) {
while (index < m && nums[index] <= query.max) {
trie.insert(nums[index]);
index += 1;
}
if (index) {
result[query.index] = trie.getMaxXor(query.xor);
}
}
return result;
};
class TrieNode {
zero = null;
one = null;
}
class BitTrie {
root = new TrieNode();
constructor(maxNum) {
this.maxBit = Math.ceil(Math.log2(maxNum));
}
insert(num) {
let node = this.root;
for (let index = this.maxBit; index >= 0; index--) {
if ((num >> index) & 1) {
node.one = node.one ?? new TrieNode();
node = node.one;
} else {
node.zero = node.zero ?? new TrieNode();
node = node.zero;
}
}
}
getMaxXor(num) {
let node = this.root;
let xor = 0;
for (let index = this.maxBit; index >= 0; index--) {
if ((num >> index) & 1) {
if (node.zero) {
xor |= 1 << index;
node = node.zero;
} else {
node = node.one;
}
} else {
if (node.one) {
xor |= 1 << index;
node = node.one;
} else {
node = node.zero;
}
}
}
return xor;
}
}