|
1 | | -# Approach 1: Implementing Parent Pointers |
| 1 | +# Approach 2: Depth-First Search on Equivalent Graph |
2 | 2 |
|
3 | 3 | # Time: O(n) |
4 | 4 | # Space: O(n) |
5 | 5 |
|
| 6 | +from collections import defaultdict |
| 7 | + |
6 | 8 | # Definition for a binary tree node. |
7 | 9 | # class TreeNode: |
8 | 10 | # def __init__(self, x): |
|
12 | 14 |
|
13 | 15 | class Solution: |
14 | 16 | def distanceK(self, root: TreeNode, target: TreeNode, k: int) -> List[int]: |
15 | | - def add_parent(curr, parent): |
16 | | - if curr: |
17 | | - curr.parent = parent |
18 | | - add_parent(curr.left, curr) |
19 | | - add_parent(curr.right, curr) |
20 | | - add_parent(root, None) |
| 17 | + graph = defaultdict(list) |
| 18 | + |
| 19 | + # Recursively build the undirected graph from the given binary tree |
| 20 | + def build_graph(curr, parent): |
| 21 | + if curr and parent: |
| 22 | + graph[curr.val].append(parent.val) |
| 23 | + graph[parent.val].append(curr.val) |
| 24 | + if curr.left: |
| 25 | + build_graph(curr.left, curr) |
| 26 | + if curr.right: |
| 27 | + build_graph(curr.right, curr) |
| 28 | + |
| 29 | + build_graph(root, None) |
21 | 30 |
|
22 | 31 | answer = [] |
23 | | - visited = set() |
| 32 | + visited = set([target.val]) |
24 | 33 |
|
25 | 34 | def dfs(curr, distance): |
26 | | - if not curr or curr in visited: |
27 | | - return |
28 | | - visited.add(curr) |
29 | | - if distance == 0: |
30 | | - answer.append(curr.val) |
| 35 | + if distance == k: |
| 36 | + answer.append(curr) |
31 | 37 | return |
32 | | - dfs(curr.parent, distance - 1) |
33 | | - dfs(curr.left, distance - 1) |
34 | | - dfs(curr.right, distance - 1) |
| 38 | + for neighbor in graph[curr]: |
| 39 | + if neighbor not in visited: |
| 40 | + visited.add(neighbor) |
| 41 | + dfs(neighbor, distance + 1) |
35 | 42 |
|
36 | | - dfs(target, k) |
| 43 | + dfs(target.val, 0) |
37 | 44 |
|
38 | 45 | return answer |
| 46 | + |
0 commit comments