字典树+离线处理。
离线处理是指不按询问的次序来回答询问,而是按照算法贪心的顺序来回答所有询问后再一次性按序回答。这里的贪心主要是把所有的询问按m值升序排列。
排序完queries数组之后,每为一个询问queries[i]查找答案,我们就把比当前m值小的数加入字典树,再在字典树上查找答案。
剩下要解决的问题就是在字典树上找最大异或对了,这是字典树的一个经典应用。
class Solution {
public:
int ch[100010*31][2];
int idx;
void insert(int x){
int p=0;
for(int i=30;~i;i--){
int j=(x>>i)&1;
if(!ch[p][j]) ch[p][j]=++idx;
p=ch[p][j];
}
}
int query(int x){
int p=0,res=0;
for(int i=30;~i;i--){
int j=(x>>i)&1;
if(ch[p][!j]){
res|=(1<<i);
p=ch[p][!j];
}else p=ch[p][j];
}
return res;
}
vector<int> maximizeXor(vector<int>& nums, vector<vector<int>>& queries) {
memset(ch,0,sizeof ch);
sort(nums.begin(),nums.end());
int m=queries.size(),mn=nums[0],l=0;
vector<int> ans(m);
for(int i=0;i<m;i++) queries[i].push_back(i);
sort(queries.begin(),queries.end(),[](const auto &a,const auto &b){
return a[1]<b[1];
});
for(auto q:queries){
if(q[1]<mn) ans[q[2]]=-1;
else{
while(l<nums.size()&&q[1]>=nums[l]) insert(nums[l++]);
ans[q[2]]=query(q[0]);
}
}
return ans;
}
};
时间复杂度:O(nlogn+mlogm+nL+mL),n为nums数组的长度,m为queries的长度,L为二进制数的长度,这里为30。
空间复杂度:O(nL)。