---
# System prepended metadata

title: 0863. All Nodes Distance K in Binary Tree
tags: [Leetcode, BFS, DFS, Medium]

---

# 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;
    }
}
```