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.
There is a rooted tree consisting of n nodes numbered 0 to n - 1. Each node's number denotes its unique genetic value (i.e. the genetic value of node x is x). The genetic difference between two genetic values is defined as the bitwise-XOR of their values. You are given the integer array parents, where parents[i] is the parent for node i. If node x is the root of the tree, then parents[x] == -1.
You are also given the array queries where queries[i] = [nodei, vali]. For each query i, find the maximum genetic difference between vali and pi, where pi is the genetic value of any node that is on the path between nodei and the root (including nodei and the root). More formally, you want to maximize vali XOR pi.
Return an array ans where ans[i] is the answer to the ith query.
Example 1:
Input: parents = [-1,0,1,1], queries = [[0,2],[3,2],[2,5]] Output: [2,3,7] Explanation: The queries are processed as follows: - [0,2]: The node with the maximum genetic difference is 0, with a difference of 2 XOR 0 = 2. - [3,2]: The node with the maximum genetic difference is 1, with a difference of 2 XOR 1 = 3. - [2,5]: The node with the maximum genetic difference is 2, with a difference of 5 XOR 2 = 7.
Example 2:
Input: parents = [3,7,-1,2,0,7,0,2], queries = [[4,6],[1,15],[0,5]] Output: [6,14,7] Explanation: The queries are processed as follows: - [4,6]: The node with the maximum genetic difference is 0, with a difference of 6 XOR 0 = 6. - [1,15]: The node with the maximum genetic difference is 1, with a difference of 15 XOR 1 = 14. - [0,5]: The node with the maximum genetic difference is 2, with a difference of 5 XOR 2 = 7.
Constraints:
2 <= parents.length <= 1050 <= parents[i] <= parents.length - 1 for every node i that is not the root.parents[root] == -11 <= queries.length <= 3 * 1040 <= nodei <= parents.length - 10 <= vali <= 2 * 105Problem summary: There is a rooted tree consisting of n nodes numbered 0 to n - 1. Each node's number denotes its unique genetic value (i.e. the genetic value of node x is x). The genetic difference between two genetic values is defined as the bitwise-XOR of their values. You are given the integer array parents, where parents[i] is the parent for node i. If node x is the root of the tree, then parents[x] == -1. You are also given the array queries where queries[i] = [nodei, vali]. For each query i, find the maximum genetic difference between vali and pi, where pi is the genetic value of any node that is on the path between nodei and the root (including nodei and the root). More formally, you want to maximize vali XOR pi. Return an array ans where ans[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 · Hash Map · Bit Manipulation · Trie
[-1,0,1,1] [[0,2],[3,2],[2,5]]
[3,7,-1,2,0,7,0,2] [[4,6],[1,15],[0,5]]
maximum-xor-with-an-element-from-array)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #1938: Maximum Genetic Difference Query
class TrieNode {
public TrieNode[] children = new TrieNode[2];
public int count = 0;
}
class Trie {
public void update(int num, int val) {
TrieNode node = root;
for (int i = HEIGHT; i >= 0; --i) {
final int bit = (num >> i) & 1;
if (node.children[bit] == null)
node.children[bit] = new TrieNode();
node = node.children[bit];
node.count += val;
}
}
public int query(int num) {
int ans = 0;
TrieNode node = root;
for (int i = HEIGHT; i >= 0; --i) {
final int bit = (num >> i) & 1;
final int targetBit = bit ^ 1;
if (node.children[targetBit] != null && node.children[targetBit].count > 0) {
ans += 1 << i;
node = node.children[targetBit];
} else {
node = node.children[targetBit ^ 1];
}
}
return ans;
}
private static final int HEIGHT = 17;
TrieNode root = new TrieNode();
}
class Solution {
public int[] maxGeneticDifference(int[] parents, int[][] queries) {
final int n = parents.length;
int[] ans = new int[queries.length];
int rootVal = -1;
List<Integer>[] tree = new List[n];
for (int i = 0; i < n; ++i)
tree[i] = new ArrayList<>();
// {node: (index, val)}
Map<Integer, List<Pair<Integer, Integer>>> nodeToQueries = new HashMap<>();
Trie trie = new Trie();
for (int i = 0; i < parents.length; ++i)
if (parents[i] == -1)
rootVal = i;
else
tree[parents[i]].add(i);
for (int i = 0; i < queries.length; ++i) {
final int node = queries[i][0];
final int val = queries[i][1];
nodeToQueries.putIfAbsent(node, new ArrayList<>());
nodeToQueries.get(node).add(new Pair<>(i, val));
}
dfs(rootVal, trie, tree, nodeToQueries, ans);
return ans;
}
private void dfs(int node, Trie trie, List<Integer>[] tree,
Map<Integer, List<Pair<Integer, Integer>>> nodeToQueries, int[] ans) {
trie.update(node, 1);
if (nodeToQueries.containsKey(node))
for (Pair<Integer, Integer> query : nodeToQueries.get(node)) {
final int i = query.getKey();
final int val = query.getValue();
ans[i] = trie.query(val);
}
for (final int child : tree[node])
dfs(child, trie, tree, nodeToQueries, ans);
trie.update(node, -1);
}
}
// Accepted solution for LeetCode #1938: Maximum Genetic Difference Query
// Auto-generated Go example from java.
func exampleSolution() {
}
// Reference (java):
// // Accepted solution for LeetCode #1938: Maximum Genetic Difference Query
// class TrieNode {
// public TrieNode[] children = new TrieNode[2];
// public int count = 0;
// }
//
// class Trie {
// public void update(int num, int val) {
// TrieNode node = root;
// for (int i = HEIGHT; i >= 0; --i) {
// final int bit = (num >> i) & 1;
// if (node.children[bit] == null)
// node.children[bit] = new TrieNode();
// node = node.children[bit];
// node.count += val;
// }
// }
//
// public int query(int num) {
// int ans = 0;
// TrieNode node = root;
// for (int i = HEIGHT; i >= 0; --i) {
// final int bit = (num >> i) & 1;
// final int targetBit = bit ^ 1;
// if (node.children[targetBit] != null && node.children[targetBit].count > 0) {
// ans += 1 << i;
// node = node.children[targetBit];
// } else {
// node = node.children[targetBit ^ 1];
// }
// }
// return ans;
// }
//
// private static final int HEIGHT = 17;
// TrieNode root = new TrieNode();
// }
//
// class Solution {
// public int[] maxGeneticDifference(int[] parents, int[][] queries) {
// final int n = parents.length;
// int[] ans = new int[queries.length];
// int rootVal = -1;
// List<Integer>[] tree = new List[n];
//
// for (int i = 0; i < n; ++i)
// tree[i] = new ArrayList<>();
//
// // {node: (index, val)}
// Map<Integer, List<Pair<Integer, Integer>>> nodeToQueries = new HashMap<>();
// Trie trie = new Trie();
//
// for (int i = 0; i < parents.length; ++i)
// if (parents[i] == -1)
// rootVal = i;
// else
// tree[parents[i]].add(i);
//
// for (int i = 0; i < queries.length; ++i) {
// final int node = queries[i][0];
// final int val = queries[i][1];
// nodeToQueries.putIfAbsent(node, new ArrayList<>());
// nodeToQueries.get(node).add(new Pair<>(i, val));
// }
//
// dfs(rootVal, trie, tree, nodeToQueries, ans);
// return ans;
// }
//
// private void dfs(int node, Trie trie, List<Integer>[] tree,
// Map<Integer, List<Pair<Integer, Integer>>> nodeToQueries, int[] ans) {
// trie.update(node, 1);
//
// if (nodeToQueries.containsKey(node))
// for (Pair<Integer, Integer> query : nodeToQueries.get(node)) {
// final int i = query.getKey();
// final int val = query.getValue();
// ans[i] = trie.query(val);
// }
//
// for (final int child : tree[node])
// dfs(child, trie, tree, nodeToQueries, ans);
//
// trie.update(node, -1);
// }
// }
# Accepted solution for LeetCode #1938: Maximum Genetic Difference Query
class TrieNode:
def __init__(self):
self.children: list[TrieNode | None] = [None] * 2
self.count = 0
class Trie:
def __init__(self):
self.root = TrieNode()
self.HEIGHT = 17
def update(self, num: int, val: int) -> None:
node = self.root
for i in range(self.HEIGHT, -1, -1):
bit = (num >> i) & 1
if not node.children[bit]:
node.children[bit] = TrieNode()
node = node.children[bit]
node.count += val
def query(self, num: int) -> int:
ans = 0
node = self.root
for i in range(self.HEIGHT, -1, -1):
bit = (num >> i) & 1
targetBit = bit ^ 1
if node.children[targetBit] and node.children[targetBit].count > 0:
ans += 1 << i
node = node.children[targetBit]
else:
node = node.children[targetBit ^ 1]
return ans
class Solution:
def maxGeneticDifference(
self,
parents: list[int],
queries: list[list[int]],
) -> list[int]:
n = len(parents)
ans = [0] * len(queries)
rootVal = -1
tree = [[] for _ in range(n)]
nodeToQueries = collections.defaultdict(list) # {node: (index, val)}
trie = Trie()
for i, parent in enumerate(parents):
if parent == -1:
rootVal = i
else:
tree[parent].append(i)
for i, (node, val) in enumerate(queries):
nodeToQueries[node].append((i, val))
def dfs(node: int) -> None:
trie.update(node, 1)
# Answer queries for node
for i, val in nodeToQueries[node]:
ans[i] = trie.query(val)
for child in tree[node]:
dfs(child)
trie.update(node, -1)
dfs(rootVal)
return ans
// Accepted solution for LeetCode #1938: Maximum Genetic Difference Query
/**
* [1938] Maximum Genetic Difference Query
*
* There is a rooted tree consisting of n nodes numbered 0 to n - 1. Each node's number denotes its unique genetic value (i.e. the genetic value of node x is x). The genetic difference between two genetic values is defined as the bitwise-XOR of their values. You are given the integer array parents, where parents[i] is the parent for node i. If node x is the root of the tree, then parents[x] == -1.
* You are also given the array queries where queries[i] = [nodei, vali]. For each query i, find the maximum genetic difference between vali and pi, where pi is the genetic value of any node that is on the path between nodei and the root (including nodei and the root). More formally, you want to maximize vali XOR pi.
* Return an array ans where ans[i] is the answer to the i^th query.
*
* Example 1:
* <img alt="" src="https://assets.leetcode.com/uploads/2021/06/29/c1.png" style="width: 118px; height: 163px;" />
* Input: parents = [-1,0,1,1], queries = [[0,2],[3,2],[2,5]]
* Output: [2,3,7]
* Explanation: The queries are processed as follows:
* - [0,2]: The node with the maximum genetic difference is 0, with a difference of 2 XOR 0 = 2.
* - [3,2]: The node with the maximum genetic difference is 1, with a difference of 2 XOR 1 = 3.
* - [2,5]: The node with the maximum genetic difference is 2, with a difference of 5 XOR 2 = 7.
*
* Example 2:
* <img alt="" src="https://assets.leetcode.com/uploads/2021/06/29/c2.png" style="width: 256px; height: 221px;" />
* Input: parents = [3,7,-1,2,0,7,0,2], queries = [[4,6],[1,15],[0,5]]
* Output: [6,14,7]
* Explanation: The queries are processed as follows:
* - [4,6]: The node with the maximum genetic difference is 0, with a difference of 6 XOR 0 = 6.
* - [1,15]: The node with the maximum genetic difference is 1, with a difference of 15 XOR 1 = 14.
* - [0,5]: The node with the maximum genetic difference is 2, with a difference of 5 XOR 2 = 7.
*
*
* Constraints:
*
* 2 <= parents.length <= 10^5
* 0 <= parents[i] <= parents.length - 1 for every node i that is not the root.
* parents[root] == -1
* 1 <= queries.length <= 3 * 10^4
* 0 <= nodei <= parents.length - 1
* 0 <= vali <= 2 * 10^5
*
*/
pub struct Solution {}
// problem: https://leetcode.com/problems/maximum-genetic-difference-query/
// discuss: https://leetcode.com/problems/maximum-genetic-difference-query/discuss/?currentPage=1&orderBy=most_votes&query=
// submission codes start here
impl Solution {
pub fn max_genetic_difference(parents: Vec<i32>, queries: Vec<Vec<i32>>) -> Vec<i32> {
vec![]
}
}
// submission codes end
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[ignore]
fn test_1938_example_1() {
let parents = vec![-1, 0, 1, 1];
let queries = vec![vec![0, 2], vec![3, 2], vec![2, 5]];
let result = vec![2, 3, 7];
assert_eq!(Solution::max_genetic_difference(parents, queries), result);
}
#[test]
#[ignore]
fn test_1938_example_2() {
let parents = vec![3, 7, -1, 2, 0, 7, 0, 2];
let queries = vec![vec![4, 6], vec![1, 15], vec![0, 5]];
let result = vec![6, 14, 7];
assert_eq!(Solution::max_genetic_difference(parents, queries), result);
}
}
// Accepted solution for LeetCode #1938: Maximum Genetic Difference Query
// Auto-generated TypeScript example from java.
function exampleSolution(): void {
}
// Reference (java):
// // Accepted solution for LeetCode #1938: Maximum Genetic Difference Query
// class TrieNode {
// public TrieNode[] children = new TrieNode[2];
// public int count = 0;
// }
//
// class Trie {
// public void update(int num, int val) {
// TrieNode node = root;
// for (int i = HEIGHT; i >= 0; --i) {
// final int bit = (num >> i) & 1;
// if (node.children[bit] == null)
// node.children[bit] = new TrieNode();
// node = node.children[bit];
// node.count += val;
// }
// }
//
// public int query(int num) {
// int ans = 0;
// TrieNode node = root;
// for (int i = HEIGHT; i >= 0; --i) {
// final int bit = (num >> i) & 1;
// final int targetBit = bit ^ 1;
// if (node.children[targetBit] != null && node.children[targetBit].count > 0) {
// ans += 1 << i;
// node = node.children[targetBit];
// } else {
// node = node.children[targetBit ^ 1];
// }
// }
// return ans;
// }
//
// private static final int HEIGHT = 17;
// TrieNode root = new TrieNode();
// }
//
// class Solution {
// public int[] maxGeneticDifference(int[] parents, int[][] queries) {
// final int n = parents.length;
// int[] ans = new int[queries.length];
// int rootVal = -1;
// List<Integer>[] tree = new List[n];
//
// for (int i = 0; i < n; ++i)
// tree[i] = new ArrayList<>();
//
// // {node: (index, val)}
// Map<Integer, List<Pair<Integer, Integer>>> nodeToQueries = new HashMap<>();
// Trie trie = new Trie();
//
// for (int i = 0; i < parents.length; ++i)
// if (parents[i] == -1)
// rootVal = i;
// else
// tree[parents[i]].add(i);
//
// for (int i = 0; i < queries.length; ++i) {
// final int node = queries[i][0];
// final int val = queries[i][1];
// nodeToQueries.putIfAbsent(node, new ArrayList<>());
// nodeToQueries.get(node).add(new Pair<>(i, val));
// }
//
// dfs(rootVal, trie, tree, nodeToQueries, ans);
// return ans;
// }
//
// private void dfs(int node, Trie trie, List<Integer>[] tree,
// Map<Integer, List<Pair<Integer, Integer>>> nodeToQueries, int[] ans) {
// trie.update(node, 1);
//
// if (nodeToQueries.containsKey(node))
// for (Pair<Integer, Integer> query : nodeToQueries.get(node)) {
// final int i = query.getKey();
// final int val = query.getValue();
// ans[i] = trie.query(val);
// }
//
// for (final int child : tree[node])
// dfs(child, trie, tree, nodeToQueries, ans);
//
// trie.update(node, -1);
// }
// }
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.
Wrong move: Zero-count keys stay in map and break distinct/count constraints.
Usually fails on: Window/map size checks are consistently off by one.
Fix: Delete keys when count reaches zero.