863. 二叉树中所有距离为 K 的结点(逐句解释代码及思路)

61 篇文章 0 订阅
解题思路

首先每个结点找到它的父结点然后存储在hashmap<TreeNode(儿子),TreeNode(父亲)>中根节点没有父亲,所以不存入里面.
然后我们这时候就可以把目标节点target看成一个新的根节点,这时候就是一个新树,距离它为K的结点也就是处在第K+1层的结点(根在第一层),这时候我们只需采用层序遍历,找到第K+1层的所有结点即可。
需要注意的是,我们的遍历只能从target开始一直向下一个方向的遍历,所以遇到原来target的父节点时,不能再返回来左右子树遍历了,也就是父节点只能添加一次,所以用一个set来存储已经添加的结点,再次遍历时,要看结点是否已经在set中,不在才能继续遍历,否则跳过。

package LeetCode.FiveHundredOneToOneThousand;

import LeetCode.TreeNode;

import java.util.*;

public class EightHundredAndSixtyThree {
    // 对所有节点添加一个指向父节点的引用,之后做广度优先搜索,找到所有距离 target 节点 K 距离的节点。
    Map<TreeNode, TreeNode> parent;
    public List<Integer> distanceK(TreeNode root, TreeNode target, int k) {
        parent = new HashMap<>();
        dfs(root,null);
        // 用队列记录
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(null);
        queue.add(target);
        // set是为了方便查询是否已经将节点存入了,防止重复
        Set<TreeNode> set = new HashSet<>();
        set.add(target);
        set.add(null);

        int dist = 0;
        while (!queue.isEmpty()){ // 队列不为空时进行循环
            TreeNode node = queue.poll();// 出栈
            if (node == null){ // 当node为空说明已经将距离为dist的节点遍历完了
                if (dist == k){ // 此时判断距离target的距离
                    List<Integer> ans = new ArrayList<>();
                    for (TreeNode n : queue)
                        ans.add(n.val);
                    return ans;
                }
                queue.offer(null);// 不相等的话就把这一层用null隔离
                dist++;
            }else {
                // 判断set是否包含有node的左右节点,如果不包含将其放入set和queue
                if (!set.contains(node.left)){
                    set.add(node.left);
                    queue.offer(node.left);
                }
                if (!set.contains(node.right)){
                    set.add(node.right);
                    queue.offer(node.right);
                }
                // 找出node的父节点,若此节点不在set中则将其放入set和queue中
                TreeNode par = parent.get(node);
                if (!set.contains(par)){
                    set.add(par);
                    queue.offer(par);
                }
            }
        }
        return new ArrayList<Integer>();
    }
    private void dfs(TreeNode root, TreeNode par){
        // 将所有的节点都存入parent中并且存入它的父节点
        if (root != null){
            parent.put(root, par);
            dfs(root.left, root);
            dfs(root.right,root);
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值