Hard
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
import java.util.Arrays;
import java.util.Comparator;
public class Solution {
static class QueryComparator implements Comparator<int[]> {
public int compare(int[] a, int[] b) {
return Integer.compare(a[1], b[1]);
}
}
static class Node {
Node zero;
Node one;
public Node() {
this.zero = null;
this.one = null;
}
}
public int[] maximizeXor(int[] nums, int[][] queries) {
Arrays.sort(nums);
int len = queries.length;
int[][] queryWithIndex = new int[len][3];
for (int i = 0; i < len; i++) {
queryWithIndex[i][0] = queries[i][0];
queryWithIndex[i][1] = queries[i][1];
queryWithIndex[i][2] = i;
}
Arrays.sort(queryWithIndex, new QueryComparator());
int numId = 0;
int[] ans = new int[len];
Node root = new Node();
for (int i = 0; i < len; i++) {
while (numId < nums.length && nums[numId] <= queryWithIndex[i][1]) {
addNumToTree(nums[numId], root);
numId++;
}
ans[queryWithIndex[i][2]] = maxXOR(queryWithIndex[i][0], root);
}
return ans;
}
private void addNumToTree(int num, Node node) {
for (int i = 31; i >= 0; i--) {
int digit = (num >> i) & 1;
if (digit == 1) {
if (node.one == null) {
node.one = new Node();
}
node = node.one;
} else {
if (node.zero == null) {
node.zero = new Node();
}
node = node.zero;
}
}
}
private int maxXOR(int num, Node node) {
if (node.one == null && node.zero == null) {
return -1;
}
int ans = 0;
for (int i = 31; i >= 0 && node != null; i--) {
int digit = (num >> i) & 1;
if (digit == 1) {
if (node.zero != null) {
ans += (1 << i);
node = node.zero;
} else {
node = node.one;
}
} else {
if (node.one != null) {
ans += (1 << i);
node = node.one;
} else {
node = node.zero;
}
}
}
return ans;
}
}