Maximum XOR of Two Numbers in an Array

Solve this Problem
Medium20–25 min
Topics
Companies
Practice:LeetCode ↗GFG ↗
Given an array of non-negative integers, find the largest value that XOR-ing any two of them together can produce. Checking every pair directly works, but there's a faster path: build the answer one bit at a time, starting from the most significant bit. At each step, tentatively assume that bit can be set, then check whether any two values in the array — reduced to just the bits decided so far — actually XOR together to hit that target. Lock the bit in only when a real pair backs it up.

Test Case 1:

Input:nums = [9, 14, 3, 21]
Output:28
Explanation:9 ^ 21 = 28, the largest XOR achievable from any pair here.

Test Case 2:

Input:nums = [8, 1, 2, 12, 7, 6]
Output:15
Explanation:8 ^ 7 = 15.

Test Case 3:

Input:nums = [0]
Output:0
Explanation:A single value has no partner to pair with, so the answer is 0.

Constraints

  • 1 ≤ nums.length ≤ 1000
  • 0 ≤ nums[i] ≤ 10⁹
🚀

Try the Dry Run

Don't just read the solution — watch it execute, one step at a time.

Approach & Solutions

Brute Force — Check Every Pair

Brute

Compare every pair directly — for each i, XOR it against every later j, and keep the largest result seen. Correct, but for even a few thousand elements that's millions of pairwise comparisons for a value that could be pinned down one bit at a time instead.

TimeO(n²)
SpaceO(1) extra
1class Solution { 2 public int maximumXor(int[] nums) { 3 int maxXor = 0; 4 for (int i = 0; i < nums.length; i++) { 5 for (int j = i + 1; j < nums.length; j++) { 6 maxXor = Math.max(maxXor, nums[i] ^ nums[j]); 7 } 8 } 9 return maxXor; 10 } 11}

Optimal — Bit-by-Bit Greedy Prefix Matching

Optimal

Build the answer one bit at a time, from the most significant bit down. At each step, tentatively assume the current best answer can gain this next bit, then check whether that's actually achievable — by truncating every value to just the bits decided so far and testing whether two of those truncated prefixes XOR together to produce the candidate. Lock the bit in only when a real pair backs it up; otherwise leave it at 0 and move to the next bit regardless.

TimeO(n)
SpaceO(n)
1class Solution { 2 public int maximumXor(int[] nums) { 3 int maxXor = 0; 4 int mask = 0; 5 for (int bit = 31; bit >= 0; bit--) { 6 mask |= (1 << bit); 7 Set<Integer> prefixes = new HashSet<>(); 8 for (int num : nums) { 9 prefixes.add(num & mask); 10 } 11 int candidate = maxXor | (1 << bit); 12 for (int prefix : prefixes) { 13 if (prefixes.contains(candidate ^ prefix)) { 14 maxXor = candidate; 15 break; 16 } 17 } 18 } 19 return maxXor; 20 } 21}

Related Problems