Maximum XOR of Two Numbers in an Array
Put every number into a binary trie from the highest bit down. Each node is one bit, 0 or 1. For each number x, walk the trie from the top bit and prefer the opposite bit, because that puts a 1 into the XOR. If the opposite child is missing, take the same child. The walk gives the largest XOR that x can make with any number. The best over all x is the answer.
The walk always stays on a path that exists in the trie, so the partner it builds is a real number from the list. At each bit it takes the opposite child whenever one exists, because that is the best choice for that bit.
Problem
You get a list of non-negative integers nums. Pick two positions in the list (they may be the same position) and XOR the two numbers. Return the largest XOR you can get.
XOR compares two numbers bit by bit. A bit of the result is 1 only when the two bits in that place are different. The same position twice gives 0, which never beats a pair of different numbers.
nums: a list of non-negative integers.
One integer: the largest value of nums[i] XOR nums[j].
5 XOR 25 = 28, which is the largest. The two largest numbers, 25 and 10, only give 25 XOR 10 = 19.
91 XOR 36 = 127, which is 1111111 in binary: seven ones in a row.
- • 1 ≤ nums.length ≤ 2 · 10^5
- • 0 ≤ nums[i] ≤ 2^31 − 1
First, think yourself
Before opening any solution, try to answer these on paper. Use hints only when stuck — each hint is counted.
- 1.
XOR gives a
1only where the two bits differ. Which bit of the answer matters most? - 2.
If I could pick any two numbers, which bit would I want to be
1first? Would the lower bits ever be worth more? - 3.
How many pairs are there if the list has 2 · 10^5 numbers?
- 4.
Suppose I already know one number
x. Could I find its best partner from its bits, without looking at every other number? - 5.
A number up to 2^31 − 1 has how many bits? In what order should I look at them?
Brute force approach
Optimized approach
Why does this algorithm work?
Dry run
All approaches compared
| Approach | Idea | Time | Space |
|---|---|---|---|
| Brute Force | XOR every pair of numbers and keep the largest; O(n²) | O(n²) | O(1) |
| Optimal | Insert every number bit by bit, highest first; for each number, walk toward the opposite bit | O(31 · n) | O(31 · n) |
Why does this belong to this pattern?
- “largest XOR of two numbers”XOR is decided bit by bit, and the top bit counts most → build the structure over bits, highest first.
- “any pair from the list”We need each number's best partner without checking all of them → a trie we can walk toward the opposite bit.
- “values up to 2^31 − 1”A fixed width of 31 bits → a trie of fixed depth 31, so each walk costs 31 steps.
This is the trie idea with bits instead of letters: each node is a 0 or a 1, and the depth is fixed at 31. The new rule is greedy: take the opposite bit whenever it exists, because 2^b is bigger than all the lower bits added together (2^b − 1 at most). Implement Trie walks the letters of one word. Here the walk follows x's bits and looks for its best partner. Maximum XOR With an Element From Array uses the same walk, with a limit on which numbers may be used.
Don't make this mistake
The highest bit is worth more than all the lower bits together, so its decision has to come first. Walking from bit 0 up decides the low bits first and locks in the high bits later. In the dry run, [3, 10, 5, 25, 2, 8] built and walked this way gives 27, not 28.
Big numbers do not make a big XOR; the bit pattern does. In the dry run, the two largest are 25 and 10, and 25 XOR 10 = 19. But 5 XOR 25 = 28, and 5 is one of the small numbers. Each number needs its own best partner.
When no number has the opposite bit, the child index is 0, which is the root. The walk then jumps back to the top and reads the wrong bits. With the dry run's 5-bit trie, this version reports 29 (for 5 and 25), but the true answer is 28.
Want to implement this?
Write it yourself on LeetCode, then come back and compare your code with the solutions above.
Open coding workspaceHow this concept connects to System Design & C++ Systems
Top engineering interviews test whether you understand how algorithms like Trie translate into production architectures and low-level memory mechanics.