Given a non-empty array of numbers, $a_0$, $a_1$, $a_2$, … , $a_{n-1}$, where $0$ ≤ $a_i$ < $2^{31}$.
Find the maximum result of $a_i$ XOR $a_j$, where 0 ≤ i, j < n.
Example:
1 2 3 4 5 6
Input: [3, 10, 5, 25, 2, 8] Output: 28 Explanation: The maximum result is 5 ^ 25 = 28.
Input: [8,10,2] Output: 10
Follow up: Could you do this in $O(n)$ runtime?
Analysis
Brute-Force
1 2 3 4 5 6 7 8 9 10 11
publicintfindMaximumXOR(int[] nums){ int n = nums.length; if (n == 1) return0; int maxVal = Integer.MIN_VALUE; for (int i = 0; i < n - 1; ++i) { for (int j = i + 1; j < n; ++j) { maxVal = Math.max(maxVal, nums[i] ^ nums[j]); } } return maxVal; }
privateintgetMax(int[] nums){ if (nums.length == 0) thrownew IllegalArgumentException(); int maxVal = nums[0]; for (int val : nums) { maxVal = Math.max(maxVal, val); } return maxVal; }
private String[] getStringArray(int[] nums, int maxLen) { int n = nums.length; String[] result = new String[n]; String format = "%" + maxLen + "s"; for (int i = 0; i < n; ++i) { result[i] = getBinaryString(nums[i], format); } return result; }
private String getBinaryString(int num, String format){ // or use toString(?, 2) return String.format(format, Integer.toBinaryString(num)).replace(' ', '0'); }
private TrieNode generateTrie(String[] numsArr){ TrieNode root = new TrieNode(); for (String s : numsArr) { // for each string TrieNode p = root; // p must be here!!!! for (int i = 0; i < s.length(); ++i) { // for each char int num = s.charAt(i) == '0' ? 0 : 1; if (p.next[num] == null) { p.next[num] = new TrieNode(); } p = p.next[num]; } } return root; }
privateintfindTheOtherInTrie(TrieNode root, int[] nums, String[] numsArr){ int n = nums.length; int maxXOR = Integer.MIN_VALUE; for (int i = 0; i < n; ++i) { String s = numsArr[i]; StringBuilder sb = new StringBuilder(); TrieNode maxP = root; TrieNode otherP = root; for (int j = 0; j < s.length(); ++j) { int num = s.charAt(j) == '0' ? 0 : 1; maxP = maxP.next[num]; // try to go to the opposite if possible int direction = otherP.next[num ^ 1] != null ? (num ^ 1) : num; sb.append(direction); otherP = otherP.next[direction]; } int otherNum = Integer.parseInt(sb.toString(), 2); // convert binary string to integer maxXOR = Math.max(maxXOR, nums[i] ^ otherNum); } return maxXOR; }