LeetCode: Maximum XOR of Two Numbers in an Array Posted on January 20, 2018July 26, 2020 by braindenny Maximum XOR of Two Numbers in an Array Similar Problems: CheatSheet: Leetcode For Code Interview CheatSheet: Common Code Problems & Follow-ups Tag: #manydetails, #trie Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 <= ai < 231. Find the maximum result of ai XOR aj, where 0 <= i, j < n. Could you do this in O(n) runtime? Example: Input: [3, 10, 5, 25, 2, 8] Output: 28 Explanation: The maximum result is 5 ^ 25 = 28. Github: code.dennyzhang.com Credits To: leetcode.com Leave me comments, if you have better ways to solve. ## https://code.dennyzhang.com/maximum-xor-of-two-numbers-in-an-array ## Basic Ideas: Trie tree ## 1. The height of tree is 32. Each node can have at most two children(0 and 1) ## 2. Append each num into the tree by bits. The lowest level is the smallest digit ## ## Identity two nodes for the target pair ## 1. Visit from top to down. If current node has only one child keep going ## 2. If it has two children, the pair should be one from the left, and one from the right ## 3. If both sub-tree has two children. f(node.left, node.right) = ## max(f(node.left.left, node.right.right), f(node.left.right, node.right.left)) ## 4. If either sub-tree has only one child, we choose it and the opposite node in the opposite sub-tree ## ## Complexity: Time O(n), Space O(n) import collections class TrieNode(object): def __init__(self): self.children = collections.defaultdict(TrieNode) self.label = None class Solution(object): def findMaximumXOR(self, nums): """ :type nums: List[int] :rtype: int """ if len(nums) == 0: return None if len(nums) == 1: return 0 # build trie tree root = TrieNode() for num in nums: v = num s = '' while v: if v%2 == 1: s = '%s%s' % ('1', s) else: s = '%s%s' % ('0', s) v = v >> 1 s = s.zfill(32) # print s # append to Trie Tree node = root for ch in s: node = node.children[ch] node.is_word = True node.label = num node = root while len(node.children) == 1: keys = node.children.keys() node = node.children[keys[0]] # all items are the same if len(node.children) == 0: return 0 # We found the first crossroad return self.findTrieMax(node.children['0'], node.children['1']) def findTrieMax(self, node1, node2): len1 = len(node1.children) len2 = len(node2.children) # reached the bottom # when len1==0, len2 will definitely be 0 if len1 == 0: return node1.label ^ node2.label elif len1 == 1 and len2 == 1: key1 = node1.children.keys()[0] key2 = node2.children.keys()[0] return self.findTrieMax(node1.children[key1], node2.children[key2]) elif len1 == 1 and len2 == 2: key1 = node1.children.keys()[0] key2 = '1' if key1 == '0' else '0' return self.findTrieMax(node1.children[key1], node2.children[key2]) elif len1 == 2 and len2 == 1: key2 = node2.children.keys()[0] key1 = '1' if key2 == '0' else '0' return self.findTrieMax(node1.children[key1], node2.children[key2]) else: return max(self.findTrieMax(node1.children['0'], node2.children['1']), \ self.findTrieMax(node1.children['1'], node2.children['0'])) Post Views: 5