# 0863. All Nodes Distance K in Binary Tree
###### tags: `Leetcode` `Medium` `DFS` `BFS`
Link: https://leetcode.com/problems/all-nodes-distance-k-in-binary-tree/
## 思路
### 思路一
HashSet记录父节点,再对以target为root的tree做dfs
### 思路二
建图+BFS
需要注意的是建图的方法是用[**链式前向星**](https://blog.csdn.net/sugarbliss/article/details/86495945)以及**在java里面实现bfs用的数据结构是linkedlist**
方法简述:
用head array的index是每个node的值,里面装的是找到的最后一个以这个index开头的边的边序号
拿着这个边序号可以在edge array里面直接当index,找到这条边的终点
在next array里面可以找到上一个之前检索到的同样的起点的边的边序号
### 思路三 recursive without hashmap
参考[这里](https://leetcode.com/problems/all-nodes-distance-k-in-binary-tree/discuss/143886/Java-O(1)-space-excluding-recursive-stack-space)
left和right用来判断subtree里面有没有target以及跟target之间的距离
val用来找距离为k的child
## Code
### 思路一
```java=
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
Map<Integer, TreeNode> parents = new HashMap<>();
List<Integer> ans = new ArrayList<>();
public List<Integer> distanceK(TreeNode root, TreeNode target, int k) {
findParents(root);
findAns(target, k, null, 0);
return ans;
}
public void findParents(TreeNode root){
if(root.left != null){
parents.put(root.left.val,root);
findParents(root.left);
}
if(root.right != null){
parents.put(root.right.val,root);
findParents(root.right);
}
}
public void findAns(TreeNode node, int k, TreeNode from, int depth){
if(node == null){
return;
}
if(depth == k){
ans.add(node.val);
return;
}
if(node.left != null && node.left != from){
findAns(node.left, k, node, depth+1);
}
if(node.right != null && node.right != from){
findAns(node.right, k, node, depth+1);
}
if(parents.get(node.val)!=from){
findAns(parents.get(node.val), k, node, depth+1);
}
}
}
```
### 思路二
```java=
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
int N = 510;
int M = N*4;
int[] head = new int[N];
int[] next = new int[M];
int[] edge = new int[M];
int index = 0;
public List<Integer> distanceK(TreeNode root, TreeNode target, int k) {
Arrays.fill(head, -1);
buildGraph(root);
return bfs(target, k);
}
public List<Integer> bfs(TreeNode target, int k){
boolean[] visited = new boolean[N];
List<Integer> ans = new ArrayList<>();
LinkedList<Integer> queue = new LinkedList<Integer>();
queue.add(target.val);
visited[target.val] = true;
while(queue.size()!=0){
int size = queue.size();
while(size-- > 0){
if(k == 0){
ans.add(queue.poll());
continue;
}
else{
for(int i = head[queue.poll()];i!=-1;i = next[i]){
int j = edge[i];
if(visited[j]==false){
queue.add(j);
visited[j] = true;
}
}
}
}
k--;
}
return ans;
}
public void addEdge(int a, int b){
edge[index] = b;
next[index] = head[a];
head[a] = index++;
}
public void buildGraph(TreeNode node){
if(node == null)return;
if(node.left != null){
addEdge(node.val, node.left.val);
addEdge(node.left.val, node.val);
buildGraph(node.left);
}
if(node.right != null){
addEdge(node.val, node.right.val);
addEdge(node.right.val, node.val);
buildGraph(node.right);
}
}
}
```
### 思路三
```java=
class Solution {
public List<Integer> distanceK(TreeNode root, TreeNode target, int k) {
List<Integer> ans = new ArrayList<>();
if(k==0){
ans.add(target.val);
return ans;
}
traverse(ans, root, target, k, 0);
return ans;
}
private int traverse(List<Integer> ans, TreeNode root, TreeNode target, int k, int val){
if(root==null) return 0;
if(val==k) ans.add(root.val);
int left = 0, right = 0;
if(val>0 || root==target){
left = traverse(ans, root.left, target, k, val+1);
right = traverse(ans, root.right, target, k, val+1);
}
else{
left = traverse(ans, root.left, target, k, val);
right = traverse(ans, root.right, target, k, val);
}
if(left==k || right==k){
ans.add(root.val);
}
if(root==target) return 1;
if(left>0) traverse(ans, root.right, target, k, left+1);
if(right>0) traverse(ans, root.left, target, k, right+1);
if(left > 0 || right > 0)
return left > 0 ? left + 1 : right + 1;
return 0;
}
}
```