一、问题描述
给定一个二叉树(具有根结点 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.
三、解题思路
距离 除了向下距离(左子节点、右子节点)还有向上距离(父节点)
- 将
target
理解为根节点,DFS (深度遍历)求解- 利用
HashMap<Integer,TreeNode>
存储节点值 -- 父节点
:获取向上的距离转化为 DFS 处理 - DFS 查找值:递归
- 利用
TreeNode from
存储节点来源:避免重复添加(来源节点的父节点的左子节点(或右子节点)又是来源节点) - 获取父节点,将深度加一执行递归:向上距离也为距离
- 利用
- 利用
public void findAns(TreeNode node,TreeNode from,int depth,int k){
if(node == null) return;
if(depth == k){//距离符合条件
ans.add(node.val);
return;
}
if(node.left != from){
findAns(node.left,node,depth+1,k);
}
if(node.right != from){
findAns(node.right,node,depth+1,k);
}
if(parent.get(node.val) != from){//获取父节点,将深度加一执行递归
findAns(parent.get(node.val),node,depth+1,k);
}
}
四、java实现
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
HashMap<Integer,TreeNode> parent = new HashMap<>();
List<Integer> ans = new ArrayList<>();
public List<Integer> distanceK(TreeNode root, TreeNode target, int k) {
if(k == 0){
ans.add(target.val);
}else{
findParents(root);
findAns(target,null,0,k);
}
return ans;
}
public void findParents(TreeNode node){
if(node != null){
if(node.left!=null){
parent.put(node.left.val,node);
findParents(node.left);
}
if(node.right!=null){
parent.put(node.right.val,node);
findParents(node.right);
}
}
}
public void findAns(TreeNode node,TreeNode from,int depth,int k){
if(node == null) return;
if(depth == k){
ans.add(node.val);
return;
}
if(node.left != from){
findAns(node.left,node,depth+1,k);
}
if(node.right != from){
findAns(node.right,node,depth+1,k);
}
if(parent.get(node.val) != from){
findAns(parent.get(node.val),node,depth+1,k);
}
}
}