Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Break down a hard problem into reliable checkpoints, edge-case handling, and complexity trade-offs.
You are given an array nums consisting of non-negative integers. You are also given a queries array, where queries[i] = [xi, mi].
The answer to the ith query is the maximum bitwise XOR value of xi and any element of nums that does not exceed mi. In other words, the answer is max(nums[j] XOR xi) for all j such that nums[j] <= mi. If all elements in nums are larger than mi, then the answer is -1.
Return an integer array answer where answer.length == queries.length and answer[i] is the answer to the ith query.
Example 1:
Input: nums = [0,1,2,3,4], queries = [[3,1],[1,3],[5,6]] Output: [3,3,7] Explanation: 1) 0 and 1 are the only two integers not greater than 1. 0 XOR 3 = 3 and 1 XOR 3 = 2. The larger of the two is 3. 2) 1 XOR 2 = 3. 3) 5 XOR 2 = 7.
Example 2:
Input: nums = [5,2,4,6,6,3], queries = [[12,4],[8,1],[6,3]] Output: [15,-1,5]
Constraints:
1 <= nums.length, queries.length <= 105queries[i].length == 20 <= nums[j], xi, mi <= 109Problem summary: You are given an array nums consisting of non-negative integers. You are also given a queries array, where queries[i] = [xi, mi]. The answer to the ith query is the maximum bitwise XOR value of xi and any element of nums that does not exceed mi. In other words, the answer is max(nums[j] XOR xi) for all j such that nums[j] <= mi. If all elements in nums are larger than mi, then the answer is -1. Return an integer array answer where answer.length == queries.length and answer[i] is the answer to the ith query.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Bit Manipulation · Trie
[0,1,2,3,4] [[3,1],[1,3],[5,6]]
[5,2,4,6,6,3] [[12,4],[8,1],[6,3]]
maximum-xor-of-two-numbers-in-an-array)maximum-genetic-difference-query)minimize-xor)maximum-strong-pair-xor-i)maximum-strong-pair-xor-ii)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #1707: Maximum XOR With an Element From Array
class Trie {
private Trie[] children = new Trie[2];
public void insert(int x) {
Trie node = this;
for (int i = 30; i >= 0; --i) {
int v = x >> i & 1;
if (node.children[v] == null) {
node.children[v] = new Trie();
}
node = node.children[v];
}
}
public int search(int x) {
Trie node = this;
int ans = 0;
for (int i = 30; i >= 0; --i) {
int v = x >> i & 1;
if (node.children[v ^ 1] != null) {
ans |= 1 << i;
node = node.children[v ^ 1];
} else if (node.children[v] != null) {
node = node.children[v];
} else {
return -1;
}
}
return ans;
}
}
class Solution {
public int[] maximizeXor(int[] nums, int[][] queries) {
Arrays.sort(nums);
int n = queries.length;
Integer[] idx = new Integer[n];
Arrays.setAll(idx, i -> i);
Arrays.sort(idx, (i, j) -> queries[i][1] - queries[j][1]);
int[] ans = new int[n];
Trie trie = new Trie();
int j = 0;
for (int i : idx) {
int x = queries[i][0], m = queries[i][1];
while (j < nums.length && nums[j] <= m) {
trie.insert(nums[j++]);
}
ans[i] = trie.search(x);
}
return ans;
}
}
// Accepted solution for LeetCode #1707: Maximum XOR With an Element From Array
type Trie struct {
children [2]*Trie
}
func NewTrie() *Trie {
return &Trie{}
}
func (t *Trie) insert(x int) {
node := t
for i := 30; i >= 0; i-- {
v := x >> i & 1
if node.children[v] == nil {
node.children[v] = NewTrie()
}
node = node.children[v]
}
}
func (t *Trie) search(x int) int {
node := t
ans := 0
for i := 30; i >= 0; i-- {
v := x >> i & 1
if node.children[v^1] != nil {
ans |= 1 << i
node = node.children[v^1]
} else if node.children[v] != nil {
node = node.children[v]
} else {
return -1
}
}
return ans
}
func maximizeXor(nums []int, queries [][]int) []int {
sort.Ints(nums)
n := len(queries)
idx := make([]int, n)
for i := 0; i < n; i++ {
idx[i] = i
}
sort.Slice(idx, func(i, j int) bool {
return queries[idx[i]][1] < queries[idx[j]][1]
})
ans := make([]int, n)
trie := NewTrie()
j := 0
for _, i := range idx {
x, m := queries[i][0], queries[i][1]
for j < len(nums) && nums[j] <= m {
trie.insert(nums[j])
j++
}
ans[i] = trie.search(x)
}
return ans
}
# Accepted solution for LeetCode #1707: Maximum XOR With an Element From Array
class Trie:
__slots__ = ["children"]
def __init__(self):
self.children = [None] * 2
def insert(self, x: int):
node = self
for i in range(30, -1, -1):
v = x >> i & 1
if node.children[v] is None:
node.children[v] = Trie()
node = node.children[v]
def search(self, x: int) -> int:
node = self
ans = 0
for i in range(30, -1, -1):
v = x >> i & 1
if node.children[v ^ 1]:
ans |= 1 << i
node = node.children[v ^ 1]
elif node.children[v]:
node = node.children[v]
else:
return -1
return ans
class Solution:
def maximizeXor(self, nums: List[int], queries: List[List[int]]) -> List[int]:
trie = Trie()
nums.sort()
j, n = 0, len(queries)
ans = [-1] * n
for i, (x, m) in sorted(zip(range(n), queries), key=lambda x: x[1][1]):
while j < len(nums) and nums[j] <= m:
trie.insert(nums[j])
j += 1
ans[i] = trie.search(x)
return ans
// Accepted solution for LeetCode #1707: Maximum XOR With an Element From Array
/**
* [1707] Maximum XOR With an Element From Array
*
* You are given an array nums consisting of non-negative integers. You are also given a queries array, where queries[i] = [xi, mi].
* The answer to the i^th query is the maximum bitwise XOR value of xi and any element of nums that does not exceed mi. In other words, the answer is max(nums[j] XOR xi) for all j such that nums[j] <= mi. If all elements in nums are larger than mi, then the answer is -1.
* Return an integer array answer where answer.length == queries.length and answer[i] is the answer to the i^th query.
*
* Example 1:
*
* Input: nums = [0,1,2,3,4], queries = [[3,1],[1,3],[5,6]]
* Output: [3,3,7]
* Explanation:
* 1) 0 and 1 are the only two integers not greater than 1. 0 XOR 3 = 3 and 1 XOR 3 = 2. The larger of the two is 3.
* 2) 1 XOR 2 = 3.
* 3) 5 XOR 2 = 7.
*
* Example 2:
*
* Input: nums = [5,2,4,6,6,3], queries = [[12,4],[8,1],[6,3]]
* Output: [15,-1,5]
*
*
* Constraints:
*
* 1 <= nums.length, queries.length <= 10^5
* queries[i].length == 2
* 0 <= nums[j], xi, mi <= 10^9
*
*/
pub struct Solution {}
// problem: https://leetcode.com/problems/maximum-xor-with-an-element-from-array/
// discuss: https://leetcode.com/problems/maximum-xor-with-an-element-from-array/discuss/?currentPage=1&orderBy=most_votes&query=
// submission codes start here
#[derive(Debug, Clone, Default)]
struct Node {
children: [Option<Box<Node>>; 2],
}
impl Node {
pub fn insert(&mut self, n: i32) {
do_insert(self, n, 31);
}
}
fn do_insert(node: &mut Node, num: i32, bit: u32) {
let b = ((num & (1 << bit)) != 0) as usize;
if node.children[b].is_none() {
node.children[b] = Some(Box::new(Node::default()));
}
if bit > 0 {
do_insert(node.children[b].as_mut().unwrap(), num, bit - 1);
}
}
impl Solution {
// Credit: https://leetcode.com/problems/maximum-xor-with-an-element-from-array/solutions/1762758/rust-trie-solution/
pub fn maximize_xor(nums: Vec<i32>, queries: Vec<Vec<i32>>) -> Vec<i32> {
let mut result_indexes = std::collections::HashMap::new();
for (idx, query) in queries.iter().enumerate() {
result_indexes
.entry((query[0], query[1]))
.or_insert(vec![])
.push(idx);
}
let mut nums = nums.clone();
let mut queries = queries.clone();
nums.sort_unstable();
queries.sort_unstable_by(|a, b| a[1].cmp(&b[1]));
let mut result = vec![0; queries.len()];
let mut trie = Node::default();
let mut next_idx = 0;
let mut last_query = None;
for query in queries.iter() {
if Some(query) == last_query {
continue;
}
last_query = Some(query);
let val = query[0];
let lim = query[1];
for idx in next_idx..nums.len() {
let n = nums[idx];
if n > lim {
break;
}
trie.insert(n);
next_idx = idx + 1;
}
let mut xored = -1;
if next_idx != 0 {
let mut node = ≜
xored = 0;
for bit in (0..32).rev() {
let is_set = (val & (1 << bit)) != 0;
match &node.children[(is_set ^ true) as usize] {
None => {
node = node.children[is_set as usize].as_ref().unwrap();
}
Some(child) => {
xored |= 1 << bit;
node = child;
}
}
}
}
for &idx in result_indexes.get(&(val, lim)).unwrap() {
result[idx] = xored;
}
}
result
}
}
// submission codes end
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_1707_example_1() {
let nums = vec![0, 1, 2, 3, 4];
let queries = vec![vec![3, 1], vec![1, 3], vec![5, 6]];
let result = vec![3, 3, 7];
assert_eq!(Solution::maximize_xor(nums, queries), result);
}
#[test]
fn test_1707_example_2() {
let nums = vec![5, 2, 4, 6, 6, 3];
let queries = vec![vec![12, 4], vec![8, 1], vec![6, 3]];
let result = vec![15, -1, 5];
assert_eq!(Solution::maximize_xor(nums, queries), result);
}
}
// Accepted solution for LeetCode #1707: Maximum XOR With an Element From Array
class Trie {
children: (Trie | null)[];
constructor() {
this.children = [null, null];
}
insert(x: number): void {
let node: Trie | null = this;
for (let i = 30; ~i; i--) {
const v = (x >> i) & 1;
if (node.children[v] === null) {
node.children[v] = new Trie();
}
node = node.children[v] as Trie;
}
}
search(x: number): number {
let node: Trie | null = this;
let ans = 0;
for (let i = 30; ~i; i--) {
const v = (x >> i) & 1;
if (node.children[v ^ 1] !== null) {
ans |= 1 << i;
node = node.children[v ^ 1] as Trie;
} else if (node.children[v] !== null) {
node = node.children[v] as Trie;
} else {
return -1;
}
}
return ans;
}
}
function maximizeXor(nums: number[], queries: number[][]): number[] {
nums.sort((a, b) => a - b);
const n = queries.length;
const idx = Array.from({ length: n }, (_, i) => i);
idx.sort((i, j) => queries[i][1] - queries[j][1]);
const ans: number[] = [];
const trie = new Trie();
let j = 0;
for (const i of idx) {
const x = queries[i][0];
const m = queries[i][1];
while (j < nums.length && nums[j] <= m) {
trie.insert(nums[j++]);
}
ans[i] = trie.search(x);
}
return ans;
}
Use this to step through a reusable interview workflow for this problem.
Sort the array in O(n log n), then scan for the missing or unique element by comparing adjacent pairs. Sorting requires O(n) auxiliary space (or O(1) with in-place sort but O(n log n) time remains). The sort step dominates.
Bitwise operations (AND, OR, XOR, shifts) are O(1) per operation on fixed-width integers. A single pass through the input with bit operations gives O(n) time. The key insight: XOR of a number with itself is 0, which eliminates duplicates without extra space.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.