【leetcode刷刷】110.平衡二叉树 、257. 二叉树的所有路径 、404.左叶子之和

文章讲述了作者在处理平衡二叉树、二叉树路径以及左叶子之和等问题时,使用递归和深度优先搜索(DFS)的方法。重点讨论了如何在递归中合理组织返回值,以及如何利用DFS进行路径遍历和判断平衡性,包括隐式回溯的概念。
摘要由CSDN通过智能技术生成

110. 平衡二叉树

  1. 我在写递归的时候,会希望返回值就是需要的值,因此选了bool作为返回值。但写着写着发现depth也是不可缺少的返回值,因此加上了depth写的递归。但是题解里面只返回一个参数depth,用depth=-1来表示不是平衡二叉树,更简洁。
  2. 迭代法:好好好复杂。。。思路其实也很简单,就是层次遍历的时候每个节点算一遍左右子树的深度,判断是不是平衡二叉树。每次算深度都要遍历树,重复计算很多的。
class Solution:
    def isBalanced(self, root: Optional[TreeNode]) -> bool:
        res, tree_depth = self.depth(root)
        return res
        

    def depth(self, root):
        # 递归法
        # 返回值是bool,左右高度,参数是root节点.需要知道左右高度。
        # 终止条件
        if not root:
            return True, 0
        
        # 一层递归
        res1, left_depth = self.depth(root.left)
        res2, right_depth = self.depth(root.right)
        return res1 and res2 and (abs(left_depth-right_depth) <= 1), max(left_depth, right_depth)+1      

257. 二叉树的所有路径

  1. 没有看题解前自己写的递归。还是之前的思路,需要的东西作为返回值,于是直接将所有路径作为返回值。但是list比较适合增加节点,因此不用str用list存储路径,得到结果后再变为str。
  2. 递归的时候需要考虑左右节点为空的情况,否则会有重复。这可能是因为空也是终止条件的缘故。按道理空应该不是终止条件,叶子节点才是终止条件。
  3. 每次递归的时候,是把root加在递归结果的前面,还蛮绕的。
class Solution:
    def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
        if not root:
            return []
        path_list = self.Paths(root)
        # print(path_list)
        res = []
        for path in path_list:
            # print(path)
            res.append("->".join(path))
        return res
        
    def Paths(self, root):
        # 也可以用递归好像
        if not root:
            return [[]]
        if not root.left and not root.right:
            return [[str(root.val)]]
        left = self.Paths(root.left)
        right = self.Paths(root.right)
        if not root.left:
            return [[str(root.val)]+path for path in right]
        if not root.right:
            return [[str(root.val)]+path for path in left]
        return [[str(root.val)]+path for path in left]+ [[str(root.val)]+path for path in right]

        # 不知道直接dfs可不可以
  1. 相比于我自己的递归,题解的递归看上去还是要舒服一点。result作为参数,也作为最终结果。path是之前经过的路径,也就是每个节点自身的路径。当遍历到叶子节点的时候,才把路径加入到result里面。(有一个默认条件是:一个节点只对应一个路径,这好像也是二叉搜索树成立的基础?)
  2. 但是回溯这部分的逻辑不是很明白。
  3. 隐形回溯也不是很明白。。
class Solution:
    def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
        if not root:
            return []
        result = []
        self.traversal(root, [], result)
        return result

    def traversal(self, cur, path, result):
        # cur不可能为空
        path.append(cur.val)
        if not cur.left and not cur.right:
            sPath = "->".join(map(str, path))
            result.append(sPath)
        if cur.left:
            self.traversal(cur.left, path, result)
            path.pop() # 回溯?
        if cur.right:
            self.traversal(cur.right, path, result)
            path.pop() # 回溯

隐形回溯1:

    def traversal(self, cur: TreeNode, path: List[int], result: List[str]) -> None:
        if not cur:
            return
        path.append(cur.val)
        if not cur.left and not cur.right:
            result.append('->'.join(map(str, path)))
        if cur.left:
            self.traversal(cur.left, path[:], result)
        if cur.right:
            self.traversal(cur.right, path[:], result)

隐形回溯2:

    def traversal(self, cur: TreeNode, path: str, result: List[str]) -> None:
        path += str(cur.val)
        # 若当前节点为leave,直接输出
        if not cur.left and not cur.right:
            result.append(path)

        if cur.left:
            # + '->' 是隐藏回溯
            self.traversal(cur.left, path + '->', result)
        
        if cur.right:
            self.traversal(cur.right, path + '->', result)

404. 左叶子之和

  1. 自己写了个递归,因为需要判断是不是左,因此加了个tag。不加的话就是再往下推一层,应该也蛮好写的
class Solution:
    def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
        # 递归的话,就是遍历,然后遍历到左叶子就加上去,否在不加?
        # 根节点不是叶子
        if not root:
            return 0
        return self.traverse(root, 0)

    # 设一个tag,左为1,右为0   
    def traverse(self, root, tag):
        if not root:
            return 0
        if tag and not root.left and not root.right:
            return root.val
        left = self.traverse(root.left, 1)
        right = self.traverse(root.right, 0)
        return left + right
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值