Skip to main content

Command Palette

Search for a command to run...

Maximum XOR of Two Numbers in an Array

Published
2 min read
C

I share my learnings here. Thanks for reading.

Problem

Given an integer array nums, return the maximum result of nums[i] XOR nums[j], where 0 <= i <= j < n. (link)

Example 1:

Input: nums = [3,10,5,25,2,8]
Output: 28
Explanation: The maximum result is 5 XOR 25 = 28.

Example 2:

Input: nums = [14,70,53,83,49,91,36,80,92,51,66,70]
Output: 127

Constraints:

  • 1 <= nums.length <= 2 * 10<sup>5</sup>

  • 0 <= nums[i] <= 2<sup>31</sup> - 1

Solution

  • Convert each number in the array to its binary form and insert it into a trie.

  • Each number can have up to 31 bits, so the trie can be 31 levels deep.

  • Each node in the trie represents a bit, either 0 or 1.

  • To find the maximum XOR, take each number and traverse the trie.

  • While traversing, look for the opposite bit (if the current bit is 0, look for 1, and vice versa) to maximize the XOR value.

  • If the opposite bit is found, move in that direction to get the maximum XOR.

  • Continue this process for each number and keep track of the highest XOR value found.

Time - O(n)

class Node {
    Node[] nodeArr;

    Node(){
        nodeArr = new Node[2];
    }

    public void put(int bit, Node node){
        nodeArr[bit] = node;
    }

    public Node get(int bit){
        return nodeArr[bit];
    }

    public boolean containsKey(int bit){
        return nodeArr[bit] != null;
    }
}

class Trie {
    Node root;

    Trie() {
        this.root = new Node(); 
    }

    public void insert(int num){
        Node node = root;
        for(int i=31; i>=0; i--){
            int bit = (num>>i) & 1;
            if(!node.containsKey(bit)){
                node.put(bit, new Node());
            }
            node = node.get(bit);
        }
    }

    public int getMax(int x){
        int ans = 0;
        Node node = root;
        for(int i=31; i>=0; i--){

            int bit = (x>>i) & 1;
            int oppBit = 1-bit;

            if(node.containsKey(oppBit)){
                ans = ans | (1<<i);
                node = node.get(oppBit);
            }
            else{
                node = node.get(bit);
            }
        }
        return ans;
    }
}

class Solution {
    public int findMaximumXOR(int[] nums) {
        Trie trie = new Trie();
        for(int i=0; i<nums.length; i++){
            trie.insert(nums[i]);
        }

        int ans = 0;

        for(int i=0; i<nums.length; i++){
            int currMax = trie.getMax(nums[i]);
            ans = Math.max(ans, currMax);
        }

        return ans;
    }
}