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
@Suppress("NAME_SHADOWING")
class Solution {
internal class QueryComparator : Comparator<IntArray> {
override fun compare(a: IntArray, b: IntArray): Int {
return a[1].compareTo(b[1])
}
}
internal class Node {
var zero: Node? = null
var one: Node? = null
}
fun maximizeXor(nums: IntArray, queries: Array<IntArray>): IntArray {
nums.sort()
val len = queries.size
val queryWithIndex = Array(len) { IntArray(3) }
for (i in 0 until len) {
queryWithIndex[i][0] = queries[i][0]
queryWithIndex[i][1] = queries[i][1]
queryWithIndex[i][2] = i
}
queryWithIndex.sortWith(QueryComparator())
var numId = 0
val ans = IntArray(len)
val root = Node()
for (i in 0 until len) {
while (numId < nums.size && nums[numId] <= queryWithIndex[i][1]) {
addNumToTree(nums[numId], root)
numId++
}
ans[queryWithIndex[i][2]] = maxXOR(queryWithIndex[i][0], root)
}
return ans
}
private fun addNumToTree(num: Int, node: Node) {
var node: Node? = node
for (i in 31 downTo 0) {
val digit = num shr i and 1
if (digit == 1) {
if (node!!.one == null) {
node.one = Node()
}
node = node.one
} else {
if (node!!.zero == null) {
node.zero = Node()
}
node = node.zero
}
}
}
private fun maxXOR(num: Int, node: Node): Int {
var node: Node? = node
if (node!!.one == null && node.zero == null) {
return -1
}
var ans = 0
var i = 31
while (i >= 0 && node != null) {
val digit = num shr i and 1
if (digit == 1) {
if (node.zero != null) {
ans += 1 shl i
node = node.zero
} else {
node = node.one
}
} else {
if (node.one != null) {
ans += 1 shl i
node = node.one
} else {
node = node.zero
}
}
i--
}
return ans
}
}