863.二叉树中所有距离为 K 的结点
给定一个二叉树(具有根结点 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” 实际上是树上的结点。
上面的输入仅仅是对这些对象进行了序列化描述。
(来源:力扣(LeetCode))
思路:使用层序遍历。
找到每个结点的父节点并用HashMap<TreeNode, TreeNode>存储他们;
根结点没有父结点所以不用存储在map里面。我们可以将目标结点target看作一个新的根结点;
距离它为K的结点也就是处在第K+1层的结点(根在第一层),使用层序遍历,找到第K+1层的所有结点;
在target遍历过程中,我们使用一个HashSet来存储已经遍历过的结点。target开始一直向下一个方向的遍历,再次遍历时,看结点是否在set中,不在才能继续遍历。
class Solution {
HashMap<TreeNode, TreeNode> map;
public List<Integer> distanceK(TreeNode root, TreeNode target, int K) {
map = new HashMap<TreeNode, TreeNode>();
HashSet<TreeNode> set = new HashSet<TreeNode>();
List<Integer> list = new LinkedList<Integer>();
Queue<TreeNode> queue = new LinkedList<TreeNode>();
if(root == null || target == null) {
return list;
}
find(root, null);
queue.add(target);
set.add(target);
while(!queue.isEmpty() && K > 0) {
int size = queue.size();
K--;
while(size > 0) {
TreeNode node = queue.poll();
if(node.left != null && set.add(node.left) == true) queue.add(node.left);
if(node.right!=null&&set.add(node.right)==true) queue.add(node.right);
if(map.containsKey(node)&&set.add(map.get(node))==true) queue.add(map.get(node));
size--;
}
}
while(!queue.isEmpty()) {
list.add(queue.poll().val);
}
return list;
}
public void find(TreeNode root, TreeNode parent) {
if (parent != null) map.put(root, parent);
if(root.left!=null) find(root.left,root);
if(root.right!=null) find(root.right,root);
}
}