Imagine you're standing at a specific node in a binary tree and need to find all nodes that are exactly k steps away from your current position. You can move to parent nodes, left children, or right children - each move counts as one step.
Given the root of a binary tree, a target node value, and an integer k, return an array containing the values of all nodes that are exactly distance k from the target node.
The beauty of this problem is that distance can be measured in any direction - up to parents or down to children!
Example: If target node has value 5 and k=2, you need to find all nodes that require exactly 2 steps to reach from node 5, whether going through parents, children, or a combination of both.
Input & Output
example_1.py — Basic Tree
$Input:root = [3,5,1,6,2,0,8,null,null,7,4], target = 5, k = 2
›Output:[7,4,1]
💡 Note:Nodes at distance 2 from target node 5 are: 7 (5→6→7), 4 (5→2→4), and 1 (5→3→1). The path can go through parents or children.
example_2.py — Single Node
$Input:root = [1], target = 1, k = 3
›Output:[]
💡 Note:There are no nodes at distance 3 from the target node 1, since the tree only has one node.
example_3.py — Distance 0
$Input:root = [3,5,1,6,2,0,8,null,null,7,4], target = 5, k = 0
›Output:[5]
💡 Note:At distance 0 from target node 5, only the target node itself qualifies.
Constraints
The number of nodes in the tree is in the range [1, 500]
0 ≤ Node.val ≤ 500
All values Node.val are unique
target is the value of one of the nodes in the tree
f
Facebook 85a
Amazon 72G
Google 68⊞
Microsoft 45
Apple 32
All Nodes Distance K in Binary Tree — Solution
The optimal solution uses parent mapping + BFS to convert the tree into an undirected graph, then performs level-order traversal from the target node. Key insight: distance in trees requires bidirectional navigation - we need parent pointers to traverse upward, combined with normal child pointers for downward traversal. Time: O(n), Space: O(n).
Common Approaches
✓
Brute Force (DFS from Every Node)
⏱️ Time: O(n²)
Space: O(h)
Visit every node in the tree, and for each node, perform a DFS to calculate its distance from the target node. If the distance equals k, add it to the result. This requires finding paths in both directions (up and down the tree).
DFS with Parent Pointers (Optimal)
⏱️ Time: O(n)
Space: O(n)
The optimal approach combines graph building and searching in a single traversal. Use DFS to find the target node while building parent relationships, then perform BFS from the target to find all nodes at distance k.
Parent Mapping + BFS
⏱️ Time: O(n)
Space: O(n)
Convert the tree into a graph by creating a hash map that stores parent-child relationships in both directions. Then use BFS starting from the target node to find all nodes at exactly distance k.
Brute Force (DFS from Every Node) — Algorithm Steps
Find the target node in the tree using DFS
For each node in the tree, calculate distance to target node
Use DFS to traverse all possible paths between nodes
Collect nodes that are exactly distance k from target
Visualization
Tap to expand
Step-by-Step Walkthrough
1
Find Target
Search entire tree to locate target node
2
Check Each Node
For every node, calculate distance to target
3
Collect Results
Add nodes with distance k to result
Code -
solution.c — C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NODES 500
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
};
static struct TreeNode* nodes[MAX_NODES];
static int nodeCount = 0;
struct TreeNode* createNode(int val) {
struct TreeNode* node = (struct TreeNode*)malloc(sizeof(struct TreeNode));
node->val = val;
node->left = NULL;
node->right = NULL;
nodes[nodeCount++] = node;
return node;
}
struct TreeNode* buildTreeFromArray(int* arr, int* isNull, int size) {
if (size == 0 || isNull[0]) {
return NULL;
}
struct TreeNode* root = createNode(arr[0]);
struct TreeNode* queue[MAX_NODES];
int front = 0, rear = 0;
queue[rear++] = root;
int i = 1;
while (front < rear && i < size) {
struct TreeNode* node = queue[front++];
if (i < size && !isNull[i]) {
node->left = createNode(arr[i]);
queue[rear++] = node->left;
}
i++;
if (i < size && !isNull[i]) {
node->right = createNode(arr[i]);
queue[rear++] = node->right;
}
i++;
}
return root;
}
struct TreeNode* findTargetNode(struct TreeNode* root, int targetVal) {
if (!root) return NULL;
if (root->val == targetVal) return root;
struct TreeNode* leftResult = findTargetNode(root->left, targetVal);
if (leftResult) return leftResult;
return findTargetNode(root->right, targetVal);
}
static struct TreeNode* parentMap[MAX_NODES];
static struct TreeNode* childMap[MAX_NODES];
static int parentMapSize = 0;
void addParentMap(struct TreeNode* child, struct TreeNode* parent) {
childMap[parentMapSize] = child;
parentMap[parentMapSize] = parent;
parentMapSize++;
}
struct TreeNode* getParent(struct TreeNode* node) {
for (int i = 0; i < parentMapSize; i++) {
if (childMap[i] == node) {
return parentMap[i];
}
}
return NULL;
}
void buildParentMap(struct TreeNode* node, struct TreeNode* parent) {
if (!node) return;
addParentMap(node, parent);
buildParentMap(node->left, node);
buildParentMap(node->right, node);
}
int isVisited(struct TreeNode** visited, int visitedSize, struct TreeNode* node) {
for (int i = 0; i < visitedSize; i++) {
if (visited[i] == node) return 1;
}
return 0;
}
int* distanceK(struct TreeNode* root, struct TreeNode* target, int k, int* returnSize) {
*returnSize = 0;
if (!root) return NULL;
parentMapSize = 0;
buildParentMap(root, NULL);
struct TreeNode* queue[MAX_NODES];
struct TreeNode* visited[MAX_NODES];
int queueFront = 0, queueRear = 0;
int visitedSize = 0;
int* result = (int*)malloc(MAX_NODES * sizeof(int));
queue[queueRear++] = target;
visited[visitedSize++] = target;
int distance = 0;
while (queueFront < queueRear && distance <= k) {
int levelSize = queueRear - queueFront;
if (distance == k) {
while (queueFront < queueRear) {
result[(*returnSize)++] = queue[queueFront++]->val;
}
break;
}
for (int i = 0; i < levelSize; i++) {
struct TreeNode* node = queue[queueFront++];
struct TreeNode* neighbors[3] = {getParent(node), node->left, node->right};
for (int j = 0; j < 3; j++) {
if (neighbors[j] && !isVisited(visited, visitedSize, neighbors[j])) {
visited[visitedSize++] = neighbors[j];
queue[queueRear++] = neighbors[j];
}
}
}
distance++;
}
return result;
}
int main() {
char line[10000];
fgets(line, sizeof(line), stdin);
int target, k;
scanf("%d\n%d", &target, &k);
// Parse tree input
int arr[MAX_NODES];
int isNull[MAX_NODES];
int size = 0;
if (strlen(line) > 1) {
char* token = strtok(line, ",\n");
while (token != NULL) {
if (strlen(token) == 0 || strcmp(token, "null") == 0 || strcmp(token, "") == 0) {
arr[size] = 0;
isNull[size] = 1;
} else {
arr[size] = atoi(token);
isNull[size] = 0;
}
size++;
token = strtok(NULL, ",\n");
}
}
// Build tree
nodeCount = 0;
struct TreeNode* root = buildTreeFromArray(arr, isNull, size);
// Find target node
struct TreeNode* targetNode = findTargetNode(root, target);
// Get result
int returnSize;
int* result = distanceK(root, targetNode, k, &returnSize);
// Output result
printf("[");
for (int i = 0; i < returnSize; i++) {
if (i > 0) printf(",");
printf("%d", result[i]);
}
printf("]\n");
// Cleanup
for (int i = 0; i < nodeCount; i++) {
free(nodes[i]);
}
free(result);
return 0;
}
Time & Space Complexity
Time Complexity
⏱️
O(n²)
For each of n nodes, we potentially traverse the entire tree to calculate distance to target
n
2n
⚠ Quadratic Growth
Space Complexity
O(h)
Recursion stack depth limited by tree height h
n
2n
✓ Linear Space
425.6K Views
HighFrequency
~18 minAvg. Time
8.5K Likes
Ln 1, Col 1
Smart Actions
💡Explanation
AI Ready
💡 SuggestionTabto acceptEscto dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen
Algorithm Visualization
Pinch to zoom • Tap outside to close
Test Cases
0 passed
0 failed
3 pending
Select Compiler
Choose a programming language
Compiler list would appear here...
AI Editor Features
Header Buttons
💡
Explain
Get a detailed explanation of your code. Select specific code or analyze the entire file. Understand algorithms, logic flow, and complexity.
🔧
Fix
Automatically detect and fix issues in your code. Finds bugs, syntax errors, and common mistakes. Shows you what was fixed.
💡
Suggest
Get improvement suggestions for your code. Best practices, performance tips, and code quality recommendations.
💬
Ask AI
Open an AI chat assistant to ask any coding questions. Have a conversation about your code, get help with debugging, or learn new concepts.
Smart Actions (Slash Commands)
🔧
/fix Enter
Find and fix issues in your code. Detects common problems and applies automatic fixes.
💡
/explain Enter
Get a detailed explanation of what your code does, including time/space complexity analysis.
🧪
/tests Enter
Automatically generate unit tests for your code. Creates comprehensive test cases.
📝
/docs Enter
Generate documentation for your code. Creates docstrings, JSDoc comments, and type hints.
⚡
/optimize Enter
Get performance optimization suggestions. Improve speed and reduce memory usage.
AI Code Completion (Copilot-style)
👻
Ghost Text Suggestions
As you type, AI suggests code completions shown in gray text. Works with keywords like def, for, if, etc.
Tabto acceptEscto dismiss
💬
Comment-to-Code
Write a comment describing what you want, and AI generates the code. Try: # two sum, # binary search, # fibonacci
💡
Pro Tip: Select specific code before using Explain, Fix, or Smart Actions to analyze only that portion. Otherwise, the entire file will be analyzed.