1. 题目来源
相关链接:[字典树] 最大异或对(trie+贪心)
2. 题目解析
很经典的一道题,trie
的经典应用。在此复习一下 trie
的不同写法。
- 时间复杂度: O ( n l o g C ) O(nlogC) O(nlogC)
- 空间复杂度: O ( n ) O(n) O(n)
代码:
const int N = 2e4+5, M = N * 32;
int son[M][2], idx;
class Solution {
public:
void insert(int x) {
int p = 0;
for (int i = 31; ~i; i -- ) {
int u = x >> i & 1;
if (!son[p][u]) son[p][u] = ++ idx;
p = son[p][u];
}
}
int query(int x) {
int res = 0, p = 0;
for (int i = 31; ~i; i -- ) {
int u = x >> i & 1;
if (son[p][!u]) p = son[p][!u], res = res * 2 + !u;
else p = son[p][u], res = res * 2 + u;
}
return res ^ x;
}
int findMaximumXOR(vector<int>& nums) {
memset(son, 0, sizeof son), idx = 0; // 注意力扣开完全局数组需要初始化
int res = 0;
for (auto e : nums)
insert(e), res = max(res, query(e));
return res;
}
};
vector
建立 trie
:
建立一个二维 vector
,首先得插入一个 {0, 0}
这个一维数组,来作为边界,也作为整个 trie
的根。利用 son[p][u] = son.size(), son.push_back({0, 0});
代替了 son[p][u] = ++ idx;
这个情况,也就是新创建一个 trie
节点的情况,并让当前节点的下标指向这个新节点,维护好当前节点到新节点的点边关系。
每个节点存下标,即建立点边关系。 需要创建新节点的时候,就是当前节点赋值为下一个节点的下标,以便能直接找到,再将下一个节点真正的创建出来,下一个节点用不用是另一回事,且走到这个 下一个节点,就意味着这条链到头了,又需要新创建节点了。
可以想象,trie
中每一条链的尾端,都会有一个节点,为 {0, 0}
,反推上去,就能到根。
创建新节点的值都是 {0, 0}
,是给二维数组添加一个一维数组,且 {0, 0}
就代表这个节点是个新节点,要不然就是 {xx, 0} or {0, xx}
放的是它下一个节点的下标,以便直接链式向下走,即 p = son[p][u]
。
在此就同理对比 son[p][u] = ++ idx
,先给 son[p][u]
这个新节点赋值为 idx
指向的下一个位置的下标。
这种 vector
建立 trie
很巧妙,但是却很慢,因为涉及到 vector
频繁增容问题。
不同的实现方式,细节也不一样,注意理解对比!
代码:
class Solution {
public:
vector<vector<int>> son;
void insert(int x) {
int p = 0;
for (int i = 31; ~i; i -- ) {
int u = x >> i & 1;
if (!son[p][u]) son[p][u] = son.size(), son.push_back({0, 0});// 每次需要多创建一个节点,作为下一个新节点
p = son[p][u];
}
}
int query(int x) {
int res = 0, p = 0;
for (int i = 31; ~i; i -- ) {
int u = x >> i & 1;
if (son[p][!u]) res = res * 2 + !u, p = son[p][!u];
else res = res * 2 + u, p = son[p][u];
}
return res ^ x;
}
int findMaximumXOR(vector<int>& nums) {
son.push_back({0, 0}); // 先插入一个一维数组作为边界,也可以看成整个 trie 的根
int res = 0;
for (auto e : nums)
insert(e), res = max(res, query(e));
return res;
}
};
还有一些其它花里胡哨的 trie
建立方式,建树,无非就是点边关系得弄清楚。 可参考这篇题解,采用哈希建树的方式…