版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sun_wangdong/article/details/82934218
给定一个二叉树(具有根结点 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" 实际上是树上的结点。 上面的输入仅仅是对这些对象进行了序列化描述。 提示:
- 给定的树是非空的,且最多有
K
个结点。 - 树上的每个结点都具有唯一的值
0 <= node.val <= 500
。 - 目标结点
target
是树上的结点。 0 <= K <= 1000
.
题解,给定一棵二叉树、一个目标节点和一个目标值k,要求给出距离该目标节点距离为k的所有节点的值,保存在一个list中,返回。拿到这道题,一开始lz有点懵,不知道该从何下手,后来结合一些网上的资料,有了一些想法,可以将给定的目标节点想成是现有的“根节点”,那么就从该“根节点”出发,去遍历,其中它的第一圈就是它的父节点和子节点,类似于层次遍历;然后遍历第二层就是距离该目标节点距离为2的节点层;以此类推,最终到达距离该目标节点距离为k的所有节点,将它们都保存在list中存储。那么可以构造成一棵新的树,如下所示:
上述原始的二叉树就变为新的一棵多叉树,其中以目标节点为根节点,以距离它最近的父节点和左右子节点为它的第一层节点,后面层的节点以此类推;那么就如同用层次遍历的方式来控制距离它k的那层,将那层节点全部输出即可。
public void setParentTreeNode(TreeNode root,Map<TreeNode,TreeNode> parentTreeNodeMap,TreeNode parent)
{ //这个函数用来求得原始二叉树的每个节点的父节点,并将它们用一个hashmap来保存
if(root == null)
return;
if(parent != null)
parentTreeNodeMap.put(root,parent);
setParentTreeNode(root.left,parentTreeNodeMap,root);
setParentTreeNode(root.right,parentTreeNodeMap,root);
}
public List<Integer> distanceK(TreeNode root,TreeNode target,int K)
{
List<Integer> retList = new ArrayList<>();
Map<TreeNode,TreeNode> parentsTreeMap = new HashMap<>();
setParentTreeNode(root,parentsTreeMap,null); //记录下二叉树中所有节点的父节点
Queue<TreeNode> checkQueue = new LinkedList<>();
checkQueue.add(target);
Set<TreeNode> hasCheck = new HashSet<>();
hasCheck.add(target);
while(!checkQueue.isEmpty() && K > 0) //用K来记录层次遍历的层数
{
K--;
int size = checkQueue.size(); //在每遍历一层时,都要先记录该层的节点数
for(int i = 0; i < size; i++)
{
TreeNode treeNode = checkQueue.poll();
if(treeNode.left != null && !hasCheck.contains(treeNode.left))
{
checkQueue.add(treeNode.left);
hasCheck.add(treeNode.left);
}
if(treeNode.right != null && !hasCheck.contains(treeNode.right))
{
checkQueue.add(treeNode.right);
hasCheck.add(treeNode.right);
}
if(parentsTreeMap.containsKey(treeNode) && !hasCheck.contains(parentsTreeMap.get(treeNode)))
{
hasCheck.add(parentsTreeMap.get(treeNode));
checkQueue.add(parentsTreeMap.get(treeNode));
}
}
}
while(!checkQueue.isEmpty()) //当k为0时,那么就表明已经到达了所需要的那一层了
retList.add(checkQueue.poll().val); //将距离目标节点距离为k的所有节点输出
return retList;
}
通过上述代码实现,可以有所收获:
1、可以用一个递归函数,通过hashmap的方式来获取每个节点的父节点
2、重新将原始二叉树进行重排,以所需要找的目标节点为新的“根节点”,去遍历每一层,其中第一层,即距离该目标节点距离为1的层,为目标节点在原二叉树中的父节点和它的左右子节点;然后将该父节点和左右子节点压入队列中,再扫描第二层,即距离该目标节点距离为2的节点,以此类推,直到找到距离该目标节点距离为k为止。
该方法很巧妙!值得好好揣摩!