Maximum XOR of Two Numbers in an Array

MediumBinary Trie · Bit Manipulation · Greedy🧩 TrieLeetCode #421 ↗Updated

Problem

Given a non-negative integer array nums, return the largest value of nums[i] ^ nums[j] over all index pairs with 0 ≤ i ≤ j < n (so pairing a number with itself, giving 0, is allowed).
Inputnums = [3,10,5,25,2,8]Output28 (5 ^ 25)
Inputnums = [14,70,53,83,49,91,36,80,92,51,66,70]Output127
Inputnums = [7]Output0

1 ≤ n ≤ 2·105  ·  0 ≤ nums[i] ≤ 231 - 1

Try it yourself

Java
class Solution {
    public int findMaximumXOR(int[] nums) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
XOR is maximised greedily from the highest bit down: winning a higher bit beats any combination of lower bits. A binary trie of the numbers lets each value ask “is there a partner with the opposite bit here?” in one step per bit.
PatternTrie

Instinct Many words, shared prefixes, and questions like "starts with", autocomplete, wildcard match or "search a board for all these words" - build a prefix tree.

Memory hack Words share their beginnings, so store each beginning once - walk one letter per step, and an end flag marks where a real word stops.

Open the Trie guide →

Approaches

Brute ForceTry Every Pair

Time O(n2)Space O(1)

XOR every pair (i, j) with i < j and keep the maximum. The answer starts at 0, which covers a single element paired with itself.

Java
public int findMaximumXOR(int[] nums) {
    int best = 0;
    for (int i = 0; i < nums.length; i++) {
        for (int j = i + 1; j < nums.length; j++) {
            best = Math.max(best, nums[i] ^ nums[j]);
        }
    }
    return best;
}

Trivially correct, but 2·1010 pairs at the upper limit.

At a glance

LevelApproachTimeSpace
Brute ForceTry Every PairO(n2)O(1)
BetterGreedy Bit-by-Bit with a Prefix Hash SetO(31 · n)O(n)
OptimalBinary Trie, Greedy Opposite-Bit WalkO(31 · n)O(31 · n)
Common pitfalls
  • Starting at bit 31: inputs are non-negative, so bit 30 is the highest that can be set.
  • Querying an empty trie — insert first (or seed with one number) so the walk never hits null.
  • In the set method, forgetting to widen mask each round, so prefixes stay too short.
Interview tips
  • Say why greedy works: bit k outweighs bits 0..k-1 combined (2k > 2k-1).
  • Draw a 3-bit trie with a couple of numbers and walk the opposite-bit path aloud.
  • Mention the hash-set version as a trie-free alternative with identical big-O.
Pattern
Binary trie over bits → maximise/minimise XOR of a value against a set of values.
My notes saved in this browser