# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def distanceK(self, root, target, K):
from collections import defaultdict, deque
# Step 1: Build the graph (parent pointers)
graph = defaultdict(list)
def buildGraph(node, parent):
if node:
if parent:
graph[node].append(parent)
graph[parent].append(node)
buildGraph(node.left, node)
buildGraph(node.right, node)
buildGraph(root, None)
# Step 2: BFS from target
queue = deque()
queue.append((target, 0))
visited = {target}
res = []
while queue:
node, dist = queue.popleft()
if dist == K:
res.append(node.val)
elif dist < K:
for neighbor in graph[node]:
if neighbor not in visited:
visited.add(neighbor)
queue.append((neighbor, dist+1))
return res
// Definition for a binary tree node.
// struct TreeNode {
// int val;
// TreeNode *left;
// TreeNode *right;
// TreeNode(int x) : val(x), left(NULL), right(NULL) {}
// };
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <queue>
class Solution {
public:
void buildGraph(TreeNode* node, TreeNode* parent, std::unordered_map<TreeNode*, std::vector<TreeNode*>>& graph) {
if (!node) return;
if (parent) {
graph[node].push_back(parent);
graph[parent].push_back(node);
}
buildGraph(node->left, node, graph);
buildGraph(node->right, node, graph);
}
std::vector<int> distanceK(TreeNode* root, TreeNode* target, int K) {
std::unordered_map<TreeNode*, std::vector<TreeNode*>> graph;
buildGraph(root, nullptr, graph);
std::queue<std::pair<TreeNode*, int>> q;
std::unordered_set<TreeNode*> visited;
q.push({target, 0});
visited.insert(target);
std::vector<int> res;
while (!q.empty()) {
auto [node, dist] = q.front(); q.pop();
if (dist == K) {
res.push_back(node->val);
} else if (dist < K) {
for (auto neighbor : graph[node]) {
if (!visited.count(neighbor)) {
visited.insert(neighbor);
q.push({neighbor, dist + 1});
}
}
}
}
return res;
}
};
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
import java.util.*;
class Solution {
public List<Integer> distanceK(TreeNode root, TreeNode target, int K) {
Map<TreeNode, List<TreeNode>> graph = new HashMap<>();
buildGraph(root, null, graph);
Queue<TreeNode> queue = new LinkedList<>();
Set<TreeNode> visited = new HashSet<>();
queue.offer(target);
visited.add(target);
int dist = 0;
while (!queue.isEmpty()) {
int size = queue.size();
if (dist == K) {
List<Integer> res = new ArrayList<>();
for (TreeNode node : queue) res.add(node.val);
return res;
}
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
for (TreeNode neighbor : graph.getOrDefault(node, new ArrayList<>())) {
if (!visited.contains(neighbor)) {
visited.add(neighbor);
queue.offer(neighbor);
}
}
}
dist++;
}
return new ArrayList<>();
}
private void buildGraph(TreeNode node, TreeNode parent, Map<TreeNode, List<TreeNode>> graph) {
if (node == null) return;
if (parent != null) {
graph.computeIfAbsent(node, x -> new ArrayList<>()).add(parent);
graph.computeIfAbsent(parent, x -> new ArrayList<>()).add(node);
}
buildGraph(node.left, node, graph);
buildGraph(node.right, node, graph);
}
}
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @param {TreeNode} target
* @param {number} K
* @return {number[]}
*/
var distanceK = function(root, target, K) {
const graph = new Map();
function buildGraph(node, parent) {
if (!node) return;
if (parent) {
if (!graph.has(node)) graph.set(node, []);
if (!graph.has(parent)) graph.set(parent, []);
graph.get(node).push(parent);
graph.get(parent).push(node);
}
buildGraph(node.left, node);
buildGraph(node.right, node);
}
buildGraph(root, null);
const queue = [];
const visited = new Set();
queue.push([target, 0]);
visited.add(target);
const res = [];
while (queue.length) {
const [node, dist] = queue.shift();
if (dist === K) {
res.push(node.val);
} else if (dist < K) {
for (const neighbor of (graph.get(node) || [])) {
if (!visited.has(neighbor)) {
visited.add(neighbor);
queue.push([neighbor, dist + 1]);
}
}
}
}
return res;
};
K
, the task is to find all nodes in the tree that are exactly K
distance away from the target node. The distance between two nodes is defined as the number of edges along the shortest path connecting them.
K
from the target node in any order.K
in a graph.
By building a map of parent relationships, we can efficiently move in all directions from any node.
K
, collect all node values at that level.We use a hash map for the graph because it provides O(1) lookups for neighbors. BFS is chosen because it naturally finds all nodes at a given distance from the start node.
Consider the following tree:
3 / \ 5 1 / \ / \ 6 2 0 8 / \ 7 4
target = 5
K = 2
Step 1: Build the graph
For each node, record its neighbors. For example, 5's neighbors are 3, 6, and 2.
Step 2: BFS from 5
Thus, both time and space complexity are O(N).