All Nodes Distance K in Binary Tree
Given the root of a binary tree, a target node, and an integer k, return the values of every node whose distance from the target is exactly k. Distance is the number of edges on the path between two nodes, and edges may be travelled in either direction — so a node above the target counts just as much as one below it. The answer may be returned in any order, and is empty if no node is that far away.
- The number of nodes in the tree is in the range [1, 500]
- 0 <= Node.val <= 500, and all values are unique
- target is guaranteed to be a node of the tree
- 0 <= k <= 1000, so k may exceed the tree's reach
root = [3,5,1,6,2,0,8,null,null,7,4], target = 5, k = 2[7,4,1]root = [3,5,1,6,2,0,8,null,null,7,4], target = 5, k = 0[5]root = [3,5,1,6,2,0,8,null,null,7,4], target = 5, k = 3[0,8]root = [1], target = 1, k = 5[]We want every node exactly k edges from the target — and an edge counts in either direction. So the answer can sit below the target, but also at its parent, its grandparent, or in a whole subtree hanging off an ancestor.
3
/ \
--> 5 1 target = 5, k = 2
/ \ / \
6 2 0 8
/ \
7 4
k = 2 from 5: 7, 4 (down through 2) AND 1 (UP to 3, then down)
answer: [7, 4, 1]Node 1 is the whole difficulty: reaching it means going up from 5 to 3 first — which the tree's pointers can't do.
Each node points to its children, never its parent, so from the target we can descend but never climb. Yet the edge between a parent and child is really two-way; we're just missing one direction. So add it: walk the tree once and record every node's parent in a map. Now each node has up to three neighbours — left child, right child, and parent.
tree pointers (down only) + parent map = undirected graph
3 every node now links
/ \ BOTH ways: to its parent
5 1 parent: 5->3, 6->5, and to its children
/ \ 2->5, 1->3, 0->1, 8->1 ...
6 2Once the edges go both ways, the tree is just an undirected graph, and "which nodes are exactly k edges away" is the standard graph move: expand outward from the target in rings — everything 1 edge away, then 2 away — and the ring reached at step k is the answer. That's breadth-first search.
One new duty: with two-way edges you can walk straight back where you came from (target → parent → target) and loop forever. So keep a visited set and admit each node once, on first arrival. BFS reaches a node by its shortest path first, so that first arrival is at its true distance — which makes blocking later arrivals both safe and necessary.
parent = {}
def map_parents(node, par):
if node is None: return
parent[node] = par
map_parents(node.left, node)
map_parents(node.right, node)
map_parents(root, None)
queue, seen, dist = deque([target]), {target}, 0
while queue:
if dist == k:
return [n.val for n in queue] # this entire ring is exactly k away
for _ in range(len(queue)): # frozen ring size — expand one ring at a time
node = queue.popleft()
for nxt in (node.left, node.right, parent[node]):
if nxt and nxt not in seen:
seen.add(nxt)
queue.append(nxt)
dist += 1
return []len(queue) is the level-boundary trick from ordinary level-order BFS, except here a "level" is a ring of equal distance, not a row of the tree.Target 5, k = 2:
ring 0: [5] expand -> children 6, 2 and parent 3
ring 1: [6, 2, 3] 6: nothing new. 2: adds 7, 4. 3: adds 1 (5 already seen)
ring 2: [7, 4, 1] dist == k -> answer [7, 4, 1]Node 1 is the payoff — reached by going up from 5 to 3, then down, a route the original pointers made impossible. And 5 never came back, because the visited set stopped 3 from stepping into it.
Building the parent map is one walk, and BFS admits each node at most once: O(N) time, O(N) space for the map, visited set, and queue. The move worth remembering: when a tree problem needs to travel upward, stop treating it as a tree and turn it into a graph — add the parent edges, then apply whatever graph algorithm the question wants (BFS for distances, DFS for reachability).
Nodes at Distance K
Multi-Directional BFS from Target
Key Mechanics
- Parent Pointers: First, build a map of parent references to enable upward traversal.
- Multi-Directional: BFS explores left, right, and parent neighbors from the target.
- Distance Tracking: Each BFS level represents distance +1 from the target.
Real-World Applications
This pattern powers social network friend suggestions (find users K connections away), organizational hierarchy queries (employees K levels from a manager), and network routing (nodes K hops from a source). The parent-pointer technique transforms trees into undirected graphs for bidirectional exploration.
Strategy
Focus on the recursive nature of trees: solve for subtrees and combine results at the root.
"Divide and Conquer: Subproblem → Recurrence → Result"