一、 题目
1. 题目描述
给你一个由非负整数组成的数组 nums
。另有一个查询数组 queries
,其中 queries[i] = [xi, mi]
。
第 i
个查询的答案是 xi
和任何 nums
数组中不超过 mi
的元素按位异或(XOR
)得到的最大值。换句话说,答案是 max(nums[j] XOR xi)
,其中所有 j
均满足 nums[j] <= mi
。如果 nums
中的所有元素都大于 mi
,最终答案就是 -1
。
返回一个整数数组 answer
作为查询的答案,其中 answer.length == queries.length
且 answer[i]
是第 i
个查询的答案。
示例 1:
输入:nums = [0,1,2,3,4], queries = [[3,1],[1,3],[5,6]]
输出:[3,3,7]
解释:
- 0 和 1 是仅有的两个不超过 1 的整数。0 XOR 3 = 3 而 1 XOR 3 = 2 。二者中的更大值是 3 。
- 1 XOR 2 = 3.
- 5 XOR 2 = 7.
示例 2:
输入:nums = [5,2,4,6,6,3], queries = [[12,4],[8,1],[6,3]]
输出:[15,-1,5]
提示:
1 <= nums.length, queries.length <= 105
queries[i].length == 2
0 <= nums[j], xi, mi <= 109
Related Topics
- 位运算
- 字典树
- 数组
- 👍 128
- 👎 0
2. 原题链接
二、 解题报告
1. 思路分析
这题用到01字典树经典应用:求最大异或和。
稍微一个改变是需要限制树中的数据,要不大于m
- 第一种思路是直接用模板,但是需要离线做,对询问和数据集排序后,从小到大的插入字典树然后询问。
- 第二种思路:https://leetcode.cn/problems/maximum-xor-with-an-element-from-array/solution/yu-shu-zu-zhong-yuan-su-de-zui-da-yi-huo-7erc/
2. 复杂度分析
时间复杂度O(nlog2n),主要是排序
3.代码实现
01字典树
。
class TrieNode:
def __init__(self,cnt=0):
self.cnt = cnt
self.next = [None]*2
self.is_end = False
def insert(self, a: int) -> None:
cur = self
for pos in range(31,-1,-1):
i = (a>>pos) & 1
if not cur.next[i] : # 没有这个字符
cur.next[i] = TrieNode()
cur = cur.next[i]
cur.cnt += 1
cur.is_end = True
def find(self,a):
ret = 0
cur = self
for pos in range(31,-1,-1):
i = (a>>pos) & 1
if i == 0:
if cur.next[1]:
cur = cur.next[1]
ret = ret*2+1
else:
cur = cur.next[0]
ret = ret*2
else:
if cur.next[0]:
cur = cur.next[0]
ret = ret*2+1
else:
cur = cur.next[1]
ret = ret*2
return ret
class Solution:
def maximizeXor(self, nums: List[int], queries: List[List[int]]) -> List[int]:
trie = TrieNode()
nums.sort()
qs = [(xm[1],xm[0],i) for i,xm in enumerate( queries)]
# (m,x,i)
qs.sort()
ans = []
i = 0
for m,x,idx in qs:
while i < len(nums) and nums[i]<=m:
trie.insert(nums[i])
i += 1
ans.append((trie.find(x) if i > 0 else -1,idx))
ans = [(b,a) for a,b in ans]
ans.sort()
ans = [a for _,a in ans]
return ans
三、 本题小结
- 要巧用离线方法