python 二叉树中所有距离为k的节点_Leetcode——863.二叉树中所有距离为 K 的结点...

这道题目要求在给定的二叉树中,找到与目标节点距离为K的所有节点。解决方案包括使用先序遍历构建反向连接的HashMap,通过BFS进行层序遍历,以及递归查找距离为K的节点。三种方法分别使用了不同的数据结构和遍历策略,但都能有效解决问题。
摘要由CSDN通过智能技术生成

给定一个二叉树(具有根结点 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.

这道题给了我们一棵二叉树,一个目标结点 target,还有一个整数K,让返回所有跟目标结点 target 相距K的结点。我们知道在子树中寻找距离为K的结点很容易,因为只需要一层一层的向下遍历即可,难点就在于符合题意的结点有可能是祖先结点,或者是在旁边的兄弟子树中,这就比较麻烦了,因为二叉树只有从父结点到子结点的路径,反过来就不行。既然没有,我们就手动创建这样的反向连接即可,这样树的遍历问题就转为了图的遍历(其实树也是一种特殊的图)。建立反向连接就是用一个 HashMap 来来建立每个结点和其父结点之间的映射,使用先序遍历建立好所有的反向连接,然后再开始查找和目标结点距离K的所有结点,这里需要一个 HashSet 来记录所有已经访问过了的结点。

在递归函数中,首先判断当前结点是否已经访问过,是的话直接返回,否则就加入到 visited 中。再判断此时K是否为0,是的话说明当前结点已经是距离目标结点为K的点了,将其加入结果 res 中,然后直接返回。否则分别对当前结点的左右子结点调用递归函数,注意此时带入 K-1,这两步是对子树进行查找。之前说了,还得对父结点,以及兄弟子树进行查找,这是就体现出建立的反向连接 HashMap 的作用了,若当前结点的父结点存在,我们也要对其父结点调用递归函数,并同样带入 K-1,这样就能正确的找到所有满足题意的点了,参见代码如下:

解法一:

class Solution {

public:

vector distanceK(TreeNode* root, TreeNode* target, int K) {

if (!root) return {};

vector res;

unordered_map parent;

unordered_set visited;

findParent(root, parent);

helper(target, K, parent, visited, res);

return res;

}

void findParent(TreeNode* node, unordered_map& parent) {

if (!node) return;

if (node->left) parent[node->left] = node;

if (node->right) parent[node->right] = node;

findParent(node->left, parent);

findParent(node->right, parent);

}

void helper(TreeNode* node, int K, unordered_map& parent, unordered_set& visited, vector& res) {

if (visited.count(node)) return;

visited.insert(node);

if (K == 0) {res.push_back(node->val); return;}

if (node->left) helper(node->left, K - 1, parent, visited, res);

if (node->right) helper(node->right, K - 1, parent, visited, res);

i

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值