【LC打卡-Python】二叉树-104, 543, 124, 687

  • 二叉树递归遍历

二叉树的一个重要思路就是递归!!!下面几题非常相似全都是递归!!

104. 二叉树的最大深度-简单

题目概述:二叉树求深度。

题目网址:https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/

题目思路:二叉树的基本操作:递归。很多对二叉树的操作思路都很相似,属于最基本但是必须掌握的类型了。不要忘记输入节点是空的基本情况。

class Solution:
    def maxDepth(self, root: TreeNode) -> int:
        if not root:
            return 0
        return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1

543. 二叉树的直径-简单

题目概述:二叉树求最长路径。

题目网址:https://leetcode-cn.com/problems/diameter-of-binary-tree/

题目思路:主要思路相似要采用递归。但是,这个最长路径要么经过节点本身,要么不经过。因为可能答案不包括根节点,这种情况其实是不在递归求解里面的,所以要针对这个情况对递归作出调整。

如果不经过节点本身,那就是在左或者右子树中有最远路径,如果经过了节点本身其实就是左子树的深度加右子树的深度。所以可以偷懒的直接用求深度的函数加递归来做:

class Solution:
    def diameterOfBinaryTree(self, root: TreeNode) -> int:
        if not root:
            return 0
        def dep(r):
            if not r:
                return 0
            return max(dep(r.left), dep(r.right)) + 1
        return max(self.diameterOfBinaryTree(root.left), self.diameterOfBinaryTree(root.right), dep(root.left) + dep(root.right)) 

更普遍而且也更好的做法是使用一个全局变量ans进行记录,每次递归都返回包含根节点的情况,如果其中不包含根节点的答案更好就更新ans,否则就不更新。以此来求最长路径:

class Solution:
    def diameterOfBinaryTree(self, root: TreeNode) -> int:
        self.ans = 0
        if not root:
            return 0

        def lr(rt):
            if not rt:
                return 0
            l = lr(rt.left)
            r = lr(rt.right)
            self.ans = max(self.ans, l + r)
            return max(l, r) + 1

        lr(root)
        return self.ans

124. 二叉树中的最大路径和-困难

题目概述:二叉树任意两节点的最大路径和,至少含一个节点。

题目网址:https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/

题目思路:这题和上一题的思路简直一摸一样。唯一的区别是,这次节点含有负数,因此要考虑当子节点为负时要舍弃。

代码和上一题几乎一样,唯一要改的算式中是加节点值。然后要注意舍弃掉负节点。

class Solution:
    def maxPathSum(self, root: TreeNode) -> int:
        self.ans = root.val
        if not root:
            return 0

        def lr(rt):
            if not rt:
                return 0
            # 舍弃负节点
            l = max(lr(rt.left), 0)
            r = max(lr(rt.right), 0)
            self.ans = max(self.ans, l + r + rt.val)
            return max(l, r) + rt.val

        lr(root)
        return self.ans

687. 最长同值路径-简单

题目概述:二叉树所有节点值相等的最长路径。

题目网址:https://leetcode-cn.com/problems/longest-univalue-path/

题目思路:这题和543题的思路也是一摸一样。唯一的区别是,节点值要相等。

class Solution:
    def longestUnivaluePath(self, root: TreeNode) -> int:
        self.ans = 0
        if not root:
            return 0

        def lr(rt):
            if not rt:
                return 0
            l = lr(rt.left)
            # 左右子节点如果和根节点树枝不一样置为0
            if l != 0:
                if rt.left.val != rt.val:
                    l = 0
            r = lr(rt.right)
            if r != 0:               
                if rt.right.val != rt.val:
                    r = 0
            self.ans = max(self.ans, l + r)
            return max(l, r) + 1

        lr(root)
        return self.ans

 

 
### Python 实现二叉树查找节点及父节点 在 Python 中实现二叉树查找节点及其父节点的功能,可以通过递归或迭代的方式来完成。以下是具体的实现方法。 #### 方法概述 为了实现这一功能,首先需要定义一个 `TreeNode` 类来表示二叉树的节点结构。接着通过递归来遍历整个二叉树,找到目标节点的同时记录其父节点的信息[^1]。 --- #### TreeNode 的定义 ```python class TreeNode: def __init__(self, value=0, left=None, right=None): self.value = value self.left = left self.right = right ``` 此部分代码定义了一个基本的二叉树节点类,其中包含了三个属性:当前节点的值 (`value`)、指向左子节点的引用 (`left`) 和指向右子节点的引用 (`right`)。 --- #### 查找节点及其父节点函数 以下是一个用于查找特定节点及其父节点的函数: ```python def find_node_and_parent(root, target_value, parent=None): """ 在二叉树中查找指定值的目标节点以及它的父节点。 参数: root (TreeNode): 当前正在访问的节点。 target_value (int): 要查找的目标节点的值。 parent (TreeNode): 记录当前节点的父节点,默认为 None。 返回: tuple: 如果找到了目标节点,则返回 (target_node, parent),否则返回 (None, None)。 """ if not root: return None, None # 找到目标节点时返回该节点和对应的父节点 if root.value == target_value: return root, parent # 递归查找左子树 result_left = find_node_and_parent(root.left, target_value, root) if result_left != (None, None): return result_left # 递归查找右子树 result_right = find_node_and_parent(root.right, target_value, root) return result_right ``` 在此函数中,参数 `root` 表示当前处理的节点;`target_value` 是我们要寻找的目标节点的值;而 `parent` 则用来追踪当前节点的父节点。如果发现匹配项,则立即返回 `(目标节点, 父节点)` 对象。如果没有找到对应节点,则最终会返回 `(None, None)`[^3]。 --- #### 测试用例 下面提供一段测试代码以验证上述逻辑是否正确工作: ```python if __name__ == "__main__": # 构建简单二叉树实例 tree_root = TreeNode(1) tree_root.left = TreeNode(2) tree_root.right = TreeNode(3) tree_root.left.left = TreeNode(4) tree_root.left.right = TreeNode(5) # 尝试查找不同数值的结果 test_values = [5, 3, 7] for val in test_values: node, parent = find_node_and_parent(tree_root, val) if node is not None and parent is not None: print(f"Found Node({node.value}) with Parent({parent.value}).") elif node is not None: print(f"Root Node Found ({node.value}), no parent.") else: print(f"No such node found for value {val}.") ``` 运行以上脚本将会打印出针对每一个待查值的相关信息或者提示未找到相应节点的消息。 --- #### 性能考虑 由于采用的是标准深度优先搜索策略(DFS),因此时间复杂度取决于给定二叉树的高度 h ,即 O(h)[^4] 。然而,在最坏情况下——退化成链表形式的一侧倾斜树里,这可能意味着接近线性的性能表现 O(n) (n代表总节点数量)。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值