【LeetCode每日一题】1707. 与数组中元素的最大异或值
题目:
给你一个由非负整数组成的数组 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]
解释:
1) 0 和 1 是仅有的两个不超过 1 的整数。0 XOR 3 = 3 而 1 XOR 3 = 2 。二者中的更大值是 3 。
2) 1 XOR 2 = 3.
3) 5 XOR 2 = 7.
示例 2:
输入:nums = [5,2,4,6,6,3], queries = [[12,4],[8,1],[6,3]]
输出:[15,-1,5]
题解:
今天这道题是421. 数组中两个数的最大异或值模板题目,和这道题大同小异。
这道题只需要进行预处理,对querys数组添加index,同时进行排序,循环过程中进行构建,构建好后,从Trie树中查询异或最大的值,随后插入数组中即可。
class Trie {
private:
static const int MAX = 1e5 * 32;
int trie[MAX][2] = {0}, idx = 0;
public:
Trie() {
}
~Trie() {
}
void add(int x) {
int p = 0;
for (int i = 30; i >= 0; i--) {
int bit = (x >> i) & 1;
if (!trie[p][bit]) trie[p][bit] = ++idx;
p = trie[p][bit];
}
}
int get(int x) {
int ans = 0;
int p = 0;
for (int i = 30; i >= 0; i--) {
int bit = (x >> i) & 1;
if (trie[p][!bit]) {
p = trie[p][!bit];
ans += (1 << i);
} else p = trie[p][bit];
}
return ans;
}
};
class Solution {
public:
vector<int> maximizeXor(vector<int>& nums, vector<vector<int>>& queries) {
vector<int> ans(queries.size());
Trie t;
for (int i = 0; i < queries.size(); i++) {
queries[i].push_back(i);
}
sort(nums.begin(), nums.end());
sort(queries.begin(), queries.end(), [](auto& a, auto& b) {
return a[1] < b[1];
});
int idx = 0;
for (auto& q : queries) {
while (idx < nums.size() && nums[idx] <= q[1]) {
t.add(nums[idx++]);
}
if (idx == 0) ans[q[2]] = -1;
else ans[q[2]] = t.get(q[0]);
}
return ans;
}
};
本节完