Mutating counts without cleanup
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.
Move from brute-force thinking to an efficient approach using hash map strategy.
Given the root of a binary tree, the value of a target node target, and an integer k, return an array of the values of all nodes that have a distance k from the target node.
You can return the answer in any order.
Example 1:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], target = 5, k = 2 Output: [7,4,1] Explanation: The nodes that are a distance 2 from the target node (with value 5) have values 7, 4, and 1.
Example 2:
Input: root = [1], target = 1, k = 3 Output: []
Constraints:
[1, 500].0 <= Node.val <= 500Node.val are unique.target is the value of one of the nodes in the tree.0 <= k <= 1000Problem summary: Given the root of a binary tree, the value of a target node target, and an integer k, return an array of the values of all nodes that have a distance k from the target node. You can return the answer in any order.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Hash Map · Tree
[3,5,1,6,2,0,8,null,null,7,4] 5 2
[1] 1 3
amount-of-time-for-binary-tree-to-be-infected)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #863: All Nodes Distance K in Binary Tree
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
private Map<TreeNode, TreeNode> g = new HashMap<>();
private List<Integer> ans = new ArrayList<>();
public List<Integer> distanceK(TreeNode root, TreeNode target, int k) {
dfs(root, null);
dfs2(target, null, k);
return ans;
}
private void dfs(TreeNode root, TreeNode fa) {
if (root == null) {
return;
}
g.put(root, fa);
dfs(root.left, root);
dfs(root.right, root);
}
private void dfs2(TreeNode root, TreeNode fa, int k) {
if (root == null) {
return;
}
if (k == 0) {
ans.add(root.val);
return;
}
for (TreeNode nxt : new TreeNode[] {root.left, root.right, g.get(root)}) {
if (nxt != fa) {
dfs2(nxt, root, k - 1);
}
}
}
}
// Accepted solution for LeetCode #863: All Nodes Distance K in Binary Tree
func distanceK(root *TreeNode, target *TreeNode, k int) []int {
g := make(map[*TreeNode]*TreeNode)
ans := []int{}
var dfs func(node, fa *TreeNode)
dfs = func(node, fa *TreeNode) {
if node == nil {
return
}
g[node] = fa
dfs(node.Left, node)
dfs(node.Right, node)
}
var dfs2 func(node, fa *TreeNode, k int)
dfs2 = func(node, fa *TreeNode, k int) {
if node == nil {
return
}
if k == 0 {
ans = append(ans, node.Val)
return
}
for _, nxt := range []*TreeNode{node.Left, node.Right, g[node]} {
if nxt != fa {
dfs2(nxt, node, k-1)
}
}
}
dfs(root, nil)
dfs2(target, nil, k)
return ans
}
# Accepted solution for LeetCode #863: All Nodes Distance K in Binary Tree
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def distanceK(self, root: TreeNode, target: TreeNode, k: int) -> List[int]:
def dfs(root, fa):
if root is None:
return
g[root] = fa
dfs(root.left, root)
dfs(root.right, root)
def dfs2(root, fa, k):
if root is None:
return
if k == 0:
ans.append(root.val)
return
for nxt in (root.left, root.right, g[root]):
if nxt != fa:
dfs2(nxt, root, k - 1)
g = {}
dfs(root, None)
ans = []
dfs2(target, None, k)
return ans
// Accepted solution for LeetCode #863: All Nodes Distance K in Binary Tree
struct Solution;
use rustgym_util::*;
use std::collections::HashMap;
use std::collections::HashSet;
use std::collections::VecDeque;
impl Solution {
fn distance_k(root: TreeLink, p: TreeLink, k: i32) -> Vec<i32> {
let k = k as usize;
let mut adj: HashMap<i32, Vec<i32>> = HashMap::new();
Self::dfs(root, &mut adj);
let mut res = vec![];
let mut queue: VecDeque<(i32, usize)> = VecDeque::new();
let start = p.unwrap().borrow().val;
let mut visited: HashSet<i32> = HashSet::new();
visited.insert(start);
queue.push_back((start, 0));
while let Some((u, d)) = queue.pop_front() {
if d == k {
res.push(u);
} else {
for &mut v in adj.entry(u).or_default() {
if visited.insert(v) {
queue.push_back((v, d + 1));
}
}
}
}
res
}
fn dfs(root: TreeLink, adj: &mut HashMap<i32, Vec<i32>>) {
if let Some(node) = root {
let mut node = node.borrow_mut();
let u = node.val;
let left = node.left.take();
let right = node.right.take();
if left.is_some() {
let v = left.as_ref().unwrap().borrow().val;
adj.entry(u).or_default().push(v);
adj.entry(v).or_default().push(u);
Self::dfs(left, adj);
}
if right.is_some() {
let v = right.as_ref().unwrap().borrow().val;
adj.entry(u).or_default().push(v);
adj.entry(v).or_default().push(u);
Self::dfs(right, adj);
}
}
}
}
#[test]
fn test() {
let root = tree!(
3,
tree!(5, tree!(6), tree!(2, tree!(7), tree!(4))),
tree!(1, tree!(0), tree!(8))
);
let p = tree!(5);
let k = 2;
let mut res = vec![7, 4, 1];
let mut ans = Solution::distance_k(root, p, k);
res.sort_unstable();
ans.sort_unstable();
assert_eq!(ans, res);
}
// Accepted solution for LeetCode #863: All Nodes Distance K in Binary Tree
/**
* Definition for a binary tree node.
* class TreeNode {
* val: number
* left: TreeNode | null
* right: TreeNode | null
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
* }
*/
function distanceK(root: TreeNode | null, target: TreeNode | null, k: number): number[] {
const g = new Map<TreeNode, TreeNode | null>();
const ans: number[] = [];
const dfs = (node: TreeNode | null, fa: TreeNode | null) => {
if (!node) {
return;
}
g.set(node, fa);
dfs(node.left, node);
dfs(node.right, node);
};
const dfs2 = (node: TreeNode | null, fa: TreeNode | null, k: number) => {
if (!node) {
return;
}
if (k === 0) {
ans.push(node.val);
return;
}
for (const nxt of [node.left, node.right, g.get(node) || null]) {
if (nxt !== fa) {
dfs2(nxt, node, k - 1);
}
}
};
dfs(root, null);
dfs2(target, null, k);
return ans;
}
Use this to step through a reusable interview workflow for this problem.
BFS with a queue visits every node exactly once — O(n) time. The queue may hold an entire level of the tree, which for a complete binary tree is up to n/2 nodes = O(n) space. This is optimal in time but costly in space for wide trees.
Every node is visited exactly once, giving O(n) time. Space depends on tree shape: O(h) for recursive DFS (stack depth = height h), or O(w) for BFS (queue width = widest level). For balanced trees h = log n; for skewed trees h = n.
Review these before coding to avoid predictable interview regressions.
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.
Wrong move: Recursive traversal assumes children always exist.
Usually fails on: Leaf nodes throw errors or create wrong depth/path values.
Fix: Handle null/base cases before recursive transitions.