We add the number into the trie and find the max possible XOR result at the same time.

Node.set() method will set the new node in the trie if needed and return the new node.

After setting the node, find the opposite bit in the trie to maximize the possible XOR result.

```
public class Solution {
public class Node {
Node one;
Node zero;
Node() {
this.one = null;
this.zero = null;
}
Node set(int n) {
if (n == 0) {
if (this.one == null) this.one = new Node();
return this.one;
}
if (this.zero == null) this.zero = new Node();
return this.zero;
}
}
public int findMaximumXOR(int[] nums) {
Node root = new Node();
int re = 0;
for (int num : nums) {
int digit = num;
int tmp = 0;
Node setNode = root;
Node findNode = root;
int pos = 30;
while (pos >= 0) {
digit = (num >> pos) & 1;
setNode = setNode.set(digit);
if (digit == 1) {
if (findNode.one != null) {
tmp = tmp | (1 << pos);
findNode = findNode.one;
} else {
findNode = findNode.zero;
}
} else {
if (findNode.zero != null) {
tmp = tmp | (1 << pos);
findNode = findNode.zero;
} else {
findNode = findNode.one;
}
}
pos--;
}
re = Math.max(re, tmp);
}
return re;
}
}
```