05 August 2008
We are given a binary tree (with root node
), a 1
root
node, and an integer value 1
target
.1
K
Return a list of the values of all nodes that have a distance
from the 1
K
node. The answer can be returned in any order.1
target
1
2
3
4
5
6
7
8
9
10
11
12
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.
Note that the inputs "root" and "target" are actually TreeNodes.
The descriptions of the inputs above are just serializations of these objects.
Note:
1
0 <= node.val <= 500
.1
target
node is a node in the tree.1
0 <= K <= 1000
.1) DFS - 对所有节点添加一个指向父节点的引用,之后做DFS,找到所有距离
节点 1
target
距离的节点。具体做法:1
K
时间复杂度O(N),空间复杂度O(N)
2) BFS,把树当作图来处理,从起始点BFS搜索路径长度为K的集合就好了,二叉树父节点到子节点好办,问题是子节点是没法回溯其父节点的,因此需要先建立左右子节点到父节点的关系,用哈希表保存。
时间复杂度O(N),空间复杂度O(N)
DFS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<Integer> distanceK(TreeNode root, TreeNode target, int K) {
Map<TreeNode, TreeNode> parents = new HashMap<>(); // 记录父节点信息
parents.put(root, null);
findNode(root, target, parents); // 在寻找目标节点的过程中,记录父节点信息,左右子节点为key,父节点为value
Map<TreeNode, TreeNode> pathParents = new HashMap<>();
cleanNonPathParent(target, parents, pathParents);
List<Integer> res = new ArrayList<>();
dfs(target, K , pathParents, res);
return res;
}
/* 找到目标节点,从跟到目标节点的路径上的节点同时需要保存父节点,哈希保存 */
private boolean findNode(TreeNode node, TreeNode target, Map<TreeNode, TreeNode> parents) {
if(node == null) { // base case1
return false;
}
if(node == target) { // base case2
return true;
}
if(node.left != null) {
parents.put(node.left, node);
if(findNode(node.left, target, parents)){
return true;
}
}
if(node.right != null ) {
parents.put(node.right, node);
return findNode(node.right, target, parents);
}
return false;
}
/* 找到root - > target 路径上的父节点信息 ,其它信息无用且会干扰后续dfs过程*/
private void cleanNonPathParent(TreeNode target, Map<TreeNode, TreeNode> parents, Map<TreeNode, TreeNode> pathParents){
while(target != null ){
pathParents.put(target, parents.get(target));
target = parents.get(target);
}
}
/* dfs, 有路径父节点的还要往上查询 */
private void dfs(TreeNode root, int k, Map<TreeNode, TreeNode> pathParents, List<Integer> res ){
if( root == null ){
return;
}
k--;
if( k < 0 ){
res.add(root.val);
return;
}
if(!pathParents.containsKey(root.left) && root.left != null){
dfs(root.left, k, pathParents, res);
}
if(!pathParents.containsKey(root.right) && root.right != null){
dfs(root.right, k, pathParents, res);
}
if(pathParents.containsKey(root) && pathParents.get(root) !=null){
dfs(pathParents.get(root), k, pathParents, res);
}
}
}
BFS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
class Solution {
//key 是子节点 value 是父节点
private HashMap<TreeNode, TreeNode> map = new HashMap<>();
//key 是子节点 value是是否访问
private HashMap<TreeNode, Boolean> visited = new HashMap<>();
private LinkedList<Integer> result = new LinkedList<>();
public List<Integer> distanceK(TreeNode root, TreeNode target, int k) {
if(k == 0) {
result.add(target.val);
return result;
}
bfs(root, null);
Queue<TreeNode> queue = new LinkedList<>();
queue.add(target);
visited.put(target, true);
int step = 0;
while(!queue.isEmpty()){
step++;
int size = queue.size();
for (int i = 0; i < size ; i++) {
TreeNode temp = queue.poll();
if (temp.left != null && !visited.get(temp.left)){
if(step == k) result.add(temp.left.val);
queue.add(temp.left);
visited.put(temp.left, true);
}
if (temp.right != null && !visited.get(temp.right)){
if(step == k) result.add(temp.right.val);
queue.add(temp.right);
visited.put(temp.right, true);
}
TreeNode parent = map.get(temp);
if(parent != null && !visited.get(parent)){
if(step == k) result.add(parent.val);
queue.add(parent);
visited.put(parent, true);
}
}
if(step == k) break;
}
return result;
}
private void bfs(TreeNode node, TreeNode parent) {
if(node == null) return;
visited.put(node, false);
map.put(node, parent);
bfs(node.left, node);
bfs(node.right, node);
}
}