C# solution (HashSet and Trie)
HashSet\nIdea\nIn order to get the maximum XOR result (assuem it iscurrMax), I will want the MSD (most significant digit) of  currMax  be 1 when iterate the dig
## HashSet\n**Idea**\nIn order to get the maximum XOR result (assuem it is```currMax```), I will want the MSD (most significant digit) of  ```currMax```  be 1 when iterate the digits from left to right, because 1XXX is always larger than 0XXX and 11XX is always larger than 10XX.\n\nWith this in mind, we will greedily try to find 2 numbers such that their XOR result at current position is 1. Now the questions becomes how to find the two numbers. As we know if a ^ b = c, then a ^ c = b. Assume a and b are the two numbers (num1, num2) we are looking for and c is  ```currMax```. In order to check whether currMax exist, we can first assume currMax exists, then we can check whether num2 exist since ```num1 ^ currMax = num2```, if num2 exists, then currMax exists.\n\nWhen at position ```i```, we only care about digits between MSD and i, so we can use a mask to only keep digits between i and MSD. The mask will be 1000000....0, 1100000....0, 1110000....0, ..., 1111111....10. Using ```mask = mask | 1 << i``` can help get correct mask for each position.\n\n**Example**\n Input: [3,10,5,25,2,8] = [00011, 01010, 00101, 11001, 00010, 01000] \n \n* i = 4, mask = 10000, set = [00000, 00000, 00000, 10000, 00000, 00000], wishMax = 10000 (exist), currMax = 10000\n* i = 3, mask = 11000, set = [00000, 01000, 00000, 11000, 00000, 01000], wishMax = 11000 (exist), currMax = 11000\n* i = 2, mask = 11100, set = [00000, 01000, 00100, 11000, 00000, 01000], wishMax = 11100 (exist), currMax = 11100\n* i = 1, mask = 11110, set = [00010, 01010, 00100, 11000, 00010, 01000], wishMax = 11110 (not exist), currMax = 11100\n* i = 0, mask = 11111, set = [00011, 01010, 00101, 11001, 00010, 01000], wishMax = 11101 (not exist), currMax = 11100\n\n**Solution: HashSet**\n``` \npublic class Solution {\n    public int FindMaximumXOR(int[] nums) {\n        \n        int currMax = 0;\n        int mask = 0;\n        \n        for(int i = 31; i >=0; i--)\n        {\n            // get mask at each position\n            mask = mask | 1 << i;\n            \n            // store digits between MSD and i in hashset\n            HashSet<int> set = new HashSet<int>();\n            foreach(int num in nums)\n                set.Add(num & mask);\n            \n            // check whether can find two numbers such that their XOR result at position i is 1.\n            int wishMax = currMax | 1 << i;\n            foreach(int n in set)\n            {\n                if(set.Contains(n ^ wishMax))\n                {\n                    currMax = wishMax;\n                    break;\n                }\n            }        \n        }\n        \n        return currMax;\n    }\n}\n```\n\n## Trie\n**Idea**\nFor each num, we will try to do XOR operation between current MSD and all other numbers at corresponding position. We first construct a Trie data structure to store all the numbers in binary format, then for each digit we will first try to get its flip digit to do XOR operation in order to get the maximum XOR result. We use a global variable to keep updating the maximum XOR result.\n\n**Solution: Trie**\n```\npublic class Solution {\n    \n    public class TrieNode\n    {\n        public TrieNode[] Children; \n        \n        public TrieNode()\n        {\n            Children = new TrieNode[2];\n        }\n    }\n    \n    public int FindMaximumXOR(int[] nums) {\n        \n        // build the Trie\n        TrieNode root = new TrieNode();\n        \n        foreach(int num in nums)\n        {\n            TrieNode curr = root;\n            \n            for(int i = 31; i >= 0; i--)\n            {\n                int currBit = (num & (1 << i)) == 0? 0 : 1;\n                if(curr.Children[currBit] == null)\n                {\n                    curr.Children[currBit] = new TrieNode(); \n                }\n                \n                curr = curr.Children[currBit];\n            }\n        }      \n        \n        // find the maximum XOR\n        int res = 0;\n        foreach(int num in nums)\n        {\n            TrieNode curr = root;\n            int currMax = 0;\n            \n            for(int i = 31; i >= 0; i--)\n            {\n                int currBit = (num & (1 << i)) == 0? 0 : 1;\n                int flipBit = currBit ^ 1;\n\n                if(curr.Children[flipBit] != null)\n                {\n                    currMax += 1 << i;\n                    curr = curr.Children[flipBit];\n                }\n                else\n                    curr = curr.Children[currBit];\n            }\n            \n            res = Math.Max(res, currMax);\n        }\n        \n        return res;\n    }\n}\n```
[]