class Node {
public:
Node* lists[2];
bool final = false;
bool containsKey(int c) {
return lists[c] != nullptr;
}
};
class Trie {
public:
Node* root;
Trie() {
root = new Node();
}
void insert(int num) {
Node* node = root;
for(int i = 31; i >= 0; i--) {
int c = ((num & (1 << i)) != 0);
if(!node->containsKey(c)) {
node->lists[c] = new Node();
}
node = node->lists[c];
}
node->final = true;
}
int invert(int c) {
return ((c == 1) ? 0 : 1);
}
int maxXOR(vector<int>& nums) {
Node* node = root;
int num = 0, ans = 0;
for(auto n : nums) {
num = 0;
node = root;
for(int i = 31; i >= 0; i--) {
int c = ((n & (1 << i)) != 0);
if(node->containsKey(invert(c))) {
num = num | (1 << i);
node = node->lists[invert(c)];
}
else{
node = node->lists[c];
}
}
if(num > ans) ans = num;
}
return ans;
}
};
class Solution {
public:
int findMaximumXOR(vector<int>& nums) {
Trie* trie = new Trie();
for(auto num : nums) {
trie->insert(num);
}
return trie->maxXOR(nums);
}
};