[leetcode] 863. All Nodes Distance K in Binary Tree @ python

本文提供了一种解决LeetCode上所有距离K的节点问题的方法,首先通过深度优先搜索(DFS)构建树节点之间的连接,形成双向图,接着使用广度优先搜索(BFS)从目标节点开始,查找距离为K的所有节点,最终返回这些节点的值。

原题

https://leetcode.com/problems/all-nodes-distance-k-in-binary-tree/

解法

先使用DFS, 构建conn字典将数的元素连接起来, 由于题目中既要向下找子树, 又要向上找, 所以我们要双向连接. 运行connect函数后, conn变成{3: [5,1], 5: [3, 6, 2], 2: [5, 7, 4], 1:[3, 0, 8]…}.

然后使用BFS, 构建当前bfs列表, 和已见过的seen集合, 然后我们做K次bfs搜索循环来找到距离K的所有节点, 搜索后将见过的节点与set取并集. 因此在第K次搜索时, bfs里的节点就是seen中没有的, 即与target节点距离K的节点了.

Time: O(n)
Space: O(n)

代码

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def distanceK(self, root, target, K):
        """
        :type root: TreeNode
        :type target: TreeNode
        :type K: int
        :rtype: List[int]
        """
        # dfs
        conn = collections.defaultdict(list)
        def connect(parent, child):
            if parent and child:
                conn[parent.val].append(child.val)
                conn[child.val].append(parent.val)                
            if child.left:
                connect(child, child.left)
            if child.right:
                connect(child, child.right)
        connect(None, root)
        # bfs
        bfs = [target.val]
        seen = set(bfs)
        for i in range(K):
            bfs = [y for x in bfs for y in conn[x] if y not in seen]
            seen = seen | set(bfs)
        return bfs
### 使用 Parent 链构建三叉链表 为了实现 `BinaryTree<String>` 的 `createByGenlist` 方法,该方法基于给定的广义表字符串来创建一棵二叉树。此过程涉及解析输入字符串并利用 parent 链建立节点之间的父子关系。 #### 解析广义表字符串 广义表是一种可以嵌套列表的数据结构形式,在这里作为描述二叉树的一种方式。每个字符代表一个结点;一对圆括号内的内容则表示子树。例如,“A(B,C(D,E))”,其中 A 是根节点,B 和 C 是其孩子节点,D 和 E 则分别是 C 的两个孩子节点。 #### 创建节点及其关联 对于每一个新读取到的字母(即非空格和括号之外的部分),都会创建一个新的 `TreeNode` 实例,并将其添加至当前正在处理中的父级节点之下。如果遇到左括号,则意味着即将进入下一层级的孩子节点序列;而当碰到右括号时,则返回至上一层次继续处理剩余部分[^1]。 ```cpp #include <iostream> #include <stack> using namespace std; struct TreeNode { string data; int parentIndex = -1; // 记录父节点索引,默认为-1表示无父节点 }; class BinaryTree { public: vector<TreeNode*> nodes; BinaryTree(const string& genListStr) : index(-1), currentParent(nullptr){ parseGenList(genListStr); } private: stack<int> parentsStack; int index; TreeNode* currentParent; void addNode(char ch) { auto newNode = new TreeNode{string(1, ch)}; if (!parentsStack.empty()) { newNode->parentIndex = parentsStack.top(); } nodes.push_back(newNode); ++index; if (currentParent != nullptr && currentParent->data.back() == '(') { parentsStack.push(index); } } void parseGenList(const string& str) { for (char c : str) { switch(c) { case '(': break; case ')': if(!parentsStack.empty()) parentsStack.pop(); break; default: addNode(c); break; } } } }; ``` 上述代码片段展示了如何通过遍历广义表达式的每一项来进行相应的操作:每当发现新的元素就调用 `addNode()` 函数增加相应的新节点;而在遇见左右括号的时候调整栈顶指针的位置以反映层级变化。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值