leetcode 关于二叉树的基本题下 python3题解

本文详细介绍了四种二叉树的遍历算法:前序遍历、后序遍历、有序数组转二叉搜索树以及平衡二叉树的判断。通过递归和迭代两种方式,阐述了每种遍历的实现思路,并提供了相应的Python代码示例。此外,还讲解了路径总和问题的解决方案,包括DFS的递归和迭代算法。这些算法的实践有助于深入理解二叉树的操作和遍历策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

144题 二叉树的前序遍历

之前都是递归做的,很好理解,直接return。这里要求用迭代算法做。这个答案也是官方题解的python答案,翻了好多发现这个最好理解...

1. 左子树value逐步推入答案,以推完作为循环结束条件,登记每一个根节点、左value的左子树;

2. 对于以上的左子树们按照从远到近的距离和依然从左到右的顺序对其右子树进行循环。距离优先级使用临时栈pop来实现,很巧妙!

3. 以临时栈的全部推入作为退出大循环的条件。

class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        if not root: return []
        result = []
        stack = []
        node = root
        while stack or node:
            while node:
                result.append(node.val)
                stack.append(node)
                node = node.left
            node = stack.pop()
            node = node.right
        return result

145题 二叉树的后序遍历

1. [root]作为一个元素,pop出来第一个就是它,根节点存入result;

2. 先左再右将子树从近到远放进临时栈。就会按照从右到左的顺序pop出子树,将逐个节点存入result,result就会是中右左+近到远,翻转即可。

class Solution:
    def postorderTraversal(self, root: TreeNode) -> List[int]:
        if not root: return []
        result = []
        s = [root]
        while s:
            node = s.pop()
            result.append(node.val)
            if node.left:
                s.append(node.left)
            if node.right:
                s.append(node.right)
        return result[::-1]

108题 有序数组转换为二叉搜索树

选择地板除中间值作为根节点,子树逐次递归。要注意一个地方:if nums必不可少。在nums存时再进行操作,否则会报各种奇怪的错。(主要是IndexError)

class Solution:
    def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
        if nums:
            mid = len(nums) // 2
            root = TreeNode(nums[mid])
            root.left = self.sortedArrayToBST(nums[0:mid])
            root.right = self.sortedArrayToBST(nums[mid+1:])
            return root

110题 平衡二叉树

肯定是要用递归的,递归本身判断balance的函数是从顶到底,这样时间复杂度比较高。

class Solution:
    def isBalanced(self, root: TreeNode) -> bool:
        def treedepth(root):
            if not root: return 0
            return 1 + max(treedepth(root.left), treedepth(root.right))
        if not root: return True
        return abs(treedepth(root.left) - treedepth(root.right)) <= 1 and self.isBalanced(root.left) and self.isBalanced(root.right)

也可以递归判断高度的函数,在函数里定下条件要求:一旦出现了绝对值>1就return大函数的false同等条件。(这个题解来源于官方题解下的一个用户Halo的热评。)

每一个节点的左右子树都判断一次,失败时直接反映到最终result

class Solution:
    def isBalanced(self, root: TreeNode) -> bool:
        def judge_treedepth(root):
            if not root: return 0
            left_depth = judge_treedepth(root.left)
            right_depth = judge_treedepth(root.right)
            if abs(left_depth - right_depth) > 1:
                result[0] = False
            return 1 + max(left_depth, right_depth)
        result = [True]
        judge_treedepth(root)
        return result[0]

112题 路径总和

DFS算法 深度优先搜索,尽可能深的搜索树的分支。递归简单,一定是体现左右孩子不存在的条件下,和等于目标值才算数。

class Solution:
    def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        if not root: return False
        if not root.left and not root.right:
            return root.val == targetSum
        return self.hasPathSum(root.left, targetSum - root.val) or self.hasPathSum(root.right, targetSum - root.val)

栈 DFS的迭代算法。把路径和节点同时保存。(来自用户 负雪明烛 题解。)这个题始终记得是要遍历到最深处的叶子节点(即节点的左右子树都不存在)并且当和等于目标值,条件成立时返回True

class Solution:
    def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        if not root: return False
        stack = []
        stack.append((root, root.val))
        while stack:
            node, path = stack.pop()
            if not node.left and not node.right and path == targetSum:
                return True 
            if node.right:
                stack.append((node.right, path + node.right.val))
            if node.left:
                stack.append((node.left, path + node.left.val))
        return False #遍历完还没能返回True即返回Fasle

二叉树这边的题做了三四天,其实根本上套路是一样的,在这个过程中细致的了解,还是要反复再去做做体会其中的算法,主要是DFS,递归以及思路上写算法问题都有点长进

声明:小白学习, 题解是写给自己看的,如有错误烦请指正~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值