二叉树中所有距离为 K 的结点

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

题目描述:

给定一个二叉树(具有根结点 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" 实际上是树上的结点。
上面的输入仅仅是对这些对象进行了序列化描述。

思路:
  • 输入:root = [3,5,1,6,2,0,8,null,null,7,4], target = 5, K = 2
  • 输出:[7,4,1]

观察示例可以看出来,结果由两部分组成的,7,4是目标节点target子树的节点,1是目标节点target上级节点子树的节点。子树的节点很好求,利用深度遍历很容易就能得到。

public void dfs(TreeNode node, Integer index) {
        if (node == null) return;
        if (index == 0) {
            list.add(node.val);
            return;
        }
      
        dfs(node.left, index - 1);
        dfs(node.right, index - 1);
    }

问题在于上级节点的子节点部分要怎么获取,首先需要维护一份当前节点与其父节点的关系。然后在进行递归的时候,除了寻找左右孩子节点,再多加一步寻找当前节点的父节点。

// 维护当前节点与其父节点的关系
public void parent(TreeNode root) {
        if (root.left != null) {
            map.put(root.left.val, root);
            parent(root.left);
        } 
        if (root.right != null) {
            map.put(root.right.val, root);
            parent(root.right);
        }
    }

public void dfs(TreeNode node,  Integer index) {
        if (node == null) return;
        if (index == 0) {
            list.add(node.val);
            return;
        }
  
        dfs(node.left, index - 1);
        dfs(node.right, index - 1);
        dfs(map.get(node.val), index - 1);
    }

遍历左右孩子的时候,也遍历其父节点,但是这里还存在一个问题,例如示例中,当你遍历target的父节点root时,又会走到root.left节点,也就是target节点,导致重复遍历,因此 我们需要记录当前节点以及上一个遍历的节点,只有不想等的时候,才遍历,防止重复遍历节点。

public void dfs(TreeNode node, TreeNode src, Integer index) {
        if (node == null) return;
        if (index == 0) {
            list.add(node.val);
            return;
        }
        if (node.left != src) 
        dfs(node.left, node, index - 1);
        if (node.right != src)
        dfs(node.right, node, index - 1);
        if (map.get(node.val) != src)
        dfs(map.get(node.val), node, index - 1);
    }
代码实现:
class Solution {
    public List list = new ArrayList();
    public Map map = new HashMap();
    public List distanceK(TreeNode root, TreeNode target, int k) {
        parent(root);
        dfs(target, null, k);
        return list;
    }
    public void dfs(TreeNode node, TreeNode src, Integer index) {
        if (node == null) return;
        if (index == 0) {
            list.add(node.val);
            return;
        }
        if (node.left != src) 
        dfs(node.left, node, index - 1);
        if (node.right != src)
        dfs(node.right, node, index - 1);
        if (map.get(node.val) != src)
        dfs(map.get(node.val), node, index - 1);
    }

    public void parent(TreeNode root) {
        if (root.left != null) {
            map.put(root.left.val, root);
            parent(root.left);
        } 
        if (root.right != null) {
            map.put(root.right.val, root);
            parent(root.right);
        }
    }
}

你可能感兴趣的:(二叉树中所有距离为 K 的结点)