LeetCode 1707 与数组中元素的最大异或值[字典树 异或] HERODING的LeetCode之路
Posted HERODING23
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 1707 与数组中元素的最大异或值[字典树 异或] HERODING的LeetCode之路相关的知识,希望对你有一定的参考价值。
解题思路:
明显不能用暴力法去解决(很可能超时),最妙的方式是字典树,首先把数组中所有元素放入字典树中,然后遍历查询数组与字典树中小的比较,难点一在于找小于阈值的字典树中的位置,第二个是判断当前数是最小数,为了找小于阈值的位置,我们把查询数组按照第二个元素的大小排序,这样字典树每次只插入不大于该数的数字,如果一个都插不进去,说明阈值数太小,直接返回-1,注释已经很详尽了,关注细节的朋友请看代码,代码如下:
class Trie
{
private:
// 0或1
Trie* next[2] = {nullptr};
public:
Trie(){}
void insert(int x) // 在前缀树中插入值x
{
Trie *root = this;
// 高位存储来Trie的前面,所以我们从左向右存储
for(int i = 29; i >= 0; i --)
{
// 取第i位的数字,30...0
int u = x >> i & 1;
// 若第u位为空,则创建一个新节点,然后root移动到下一个节点
if(!root->next[u]) root -> next[u] = new Trie();
root = root -> next[u];
}
}
int search(int x) // 在前缀树中寻找 x 的最大异或值
{
Trie *root = this;
// res表示最大异或值,每次res*2表示左移一位,31循环后左移了31位了,+u表示加上当前的最低位数字
int res = 0;
for(int i = 29; i >= 0; i --)
{
int u = x >> i & 1;
// 若 x 的第 u 位存在,我们走到相反的方向去,因为异或总是|值|相反才取最大值的
if(root -> next[!u]) root = root -> next[!u], res = res * 2 + !u;
// 相反方向的节点为空,只能顺着相同方向走了
else root = root->next[u], res = res * 2 + u;
}
// 由于上面我们得到的异或另一个数组元素,此时我们需要将这个数组元素与x异或得到 两个数的最大异或值
res ^= x;
return res;
}
};
bool cmp(vector<int>& q1, vector<int>& q2) {
return q1[1] < q2[1];
}
class Solution {
public:
vector<int> maximizeXor(vector<int>& nums, vector<vector<int>>& queries) {
// 给nums排序,为了从小到大插入
sort(nums.begin(), nums.end());
int numQ = queries.size();
// 提前给 queries 编号,不然排序会打乱顺序
for(int i = 0; i < numQ; i ++) {
queries[i].push_back(i);
}
sort(queries.begin(), queries.end(), cmp);
vector<int> res(numQ);
Trie *root = new Trie();
int index = 0, len = nums.size();
for(auto& query : queries) {
// 如果长度没超过且满足条件
while(index < len && nums[index] <= query[1]) {
root -> insert(nums[index]);
index ++;
}
if(index == 0) {
res[query[2]] = -1;
} else {
res[query[2]] = root -> search(query[0]);
}
}
return res;
}
};
/*作者:heroding
链接:https://leetcode-cn.com/problems/maximum-xor-with-an-element-from-array/solution/czui-xiang-xi-zhu-shi-zi-dian-shu-by-her-8bcx/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。*/
以上是关于LeetCode 1707 与数组中元素的最大异或值[字典树 异或] HERODING的LeetCode之路的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode每日一题——1707. 与数组中元素的最大异或值(字典树)