问题描述

给定一个二叉树(具有根结点 root), 一个目标结点 target ,和一个整数值 K 。

返回到目标结点 target 距离为 K 的所有结点的值的列表。 答案可以以任何顺序返回。

 

示例 1:

输入:root = [3,5,1,6,2,0,8,null,null,7,4], target = 5, K = 2
输出:[7,4,1]
解释:
所求结点为与目标结点(值为 5)距离为 2 的结点,
值分别为 7,4,以及 1

 


注意,输入的 "root" 和 "target" 实际上是树上的结点。
上面的输入仅仅是对这些对象进行了序列化描述。
 

提示:

给定的树是非空的。
树上的每个结点都具有唯一的值 0 <= node.val <= 500 。
目标结点 target 是树上的结点。
0 <= K <= 1000.

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/all-nodes-distance-k-in-binary-tree

解答

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 * 将二叉树转换成无向图,存放在hashmap中,再从target节点进行k次bfs即可。
 */
class Solution {
    Map<Integer, List<Integer>> graph;
    Map<Integer, Integer> visited;
    int maxDeep;
    public void dfs(TreeNode root, int deep){
        if(root == null){
            if(maxDeep < deep)maxDeep = deep;
            return;
        }
        dfs(root.left, deep+1);
        dfs(root.right, deep+1);
        if(root.left != null){
            if(!graph.containsKey(root.val))graph.put(root.val, new ArrayList<Integer>());
            graph.get(root.val).add(root.left.val);
            if(!graph.containsKey(root.left.val))graph.put(root.left.val, new ArrayList<Integer>());
            graph.get(root.left.val).add(root.val);
        }
        if(root.right != null){
            if(!graph.containsKey(root.val))graph.put(root.val, new ArrayList<Integer>());
            graph.get(root.val).add(root.right.val);
            if(!graph.containsKey(root.right.val))graph.put(root.right.val, new ArrayList<Integer>());
            graph.get(root.right.val).add(root.val);
        }
    }
    public List<Integer> distanceK(TreeNode root, TreeNode target, int K) {
        maxDeep = 0;
        graph = new HashMap<Integer, List<Integer>>();
        visited = new HashMap<Integer, Integer>();
        List<Integer> res = new ArrayList<Integer>();
        if(root == null)return res;
        dfs(root, 0);
        if(maxDeep == 1 && K > 1)return res;
        if(K > (maxDeep-1)*2)return res;
        Queue<Integer> queue = new LinkedList<Integer>();
        queue.offer(target.val);
        while(K!=0){
            int len = queue.size();
            for(int i=0;i<len;i++){
                int p = queue.poll();
                visited.put(p,1);
                for(int tempNum:graph.get(p)){
                    if(!visited.containsKey(tempNum))queue.offer(tempNum);
                }
            }
            K--;
        }
        return new ArrayList<Integer>(queue);
    }
}