Leetcode 513, 112

题目:树左下角的值

学习资料:代码随想录

实现过程

  • 迭代法:层序遍历,遍历到最后一层返回最左侧的,i=0就是每一层最左边的结点。
  • 递归法:需要记录深度最大的叶子结点,然后使用前序遍历,返回深度最大的结点,这样就是最左侧的

迭代法

        #记录最后一行中最左侧的

        queue = [root]
        result = 0
        while queue:
            
            size = len(queue)

            for i in range(size):
                if i == 0:
                    result = queue[0].val
                
                cur = queue.pop(0)

                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
        return result

递归法

        maxLen_ = float("-inf")
        result = 0
        

        def tranversal(root, depth):
            nonlocal maxLen_, result
            if not root.left and not root.right:
                if depth > maxLen_:
                    maxLen_ = depth
                    result = root.val
            
            if root.left:
                depth += 1
                tranversal(root.left, depth)
                depth -= 1
            if root.right:
                depth += 1
                tranversal(root.right, depth)
                depth -= 1
            return
        
        tranversal(root, 0)
        return result

Leetcode 112

题目:路径总和

学习资料:代码随想录

实现过程

  • 递归方法:
    • 参数需要root和计数器counter;可以采用递减的方式,当碰到叶子结点同时counter为0时就返回True
    • 终止条件就是,当碰到叶子结点同时counter为0时就返回True;如果碰到叶子结点路径不满足,返回False
    • 单层逻辑:不考虑空结点,要进行回溯;如果直接在参数位置进行counter计算则是隐藏回溯
  • 注意初始放入的逻辑是counter减去root的val,这里counter记录的是剩余的总和
        def tranversal(root, counter):
            if (not root.left) and (not root.right) and counter == 0:
                return True
            if not root.left and not root.right:
                return False

            if root.left:
                
                counter -= root.left.val
                if tranversal(root.left, counter):
                    return True
                counter += root.left.val

            if root.right:
                counter -= root.right.val
                if tranversal(root.right, counter):
                    return True
                counter += root.right.val

            return False
        
        if root == None:
            return False
        else:
            return tranversal(root, targetSum-root.val)

Leetcode 113

题目:路径总和

学习资料: 代码随想录

实现过程

  • 递归三部曲:
    • 传入参数:结点和计数器count,注意计数器使用减法的方式
    • 终止条件:同上;两个终止条件:当count为0且为叶子结点证明路径找到,添加到结果中;如果为叶子结点但不为0,则没有找到
    • 单层循环:利用到回溯的思想;需要path来存储路径,result存储结果;要pop出之前添加的结点
    def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
        result = []
        path = []
        def trace(cur, count):

            if not cur.left and not cur.right and count == 0:

                result.append(path[:])

                return
            if not cur.left and not cur.right:
                return

            if cur.left:
                path.append(cur.left.val)
                trace(cur.left, count - cur.left.val)
                path.pop()
            if cur.right:
                path.append(cur.right.val)
                trace(cur.right, count - cur.right.val)
                path.pop()
            # return
        # 判读空的情况
        if not root:return result
        path.append(root.val)
        trace(root, targetSum - root.val)

        return result 

Leetcode 106

题目:中序后序构造二叉树

学习资料: 代码随想录

实现过程

  • 后序数组长度为0,则为空节点
  • 从后序数组中最后一个数字得到root节点
  • 根据root节点,在中序数组中找到对应的index
  • 根据index划分中序数组,左区间和右区间
  • 根据中序数组的左右区间划分后序数组
  • 递归上述过程,最终返回root
  • 如果后序长度为1说明,为叶子节点或者只有一个root,直接返回root
    def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:

        def trace(inorder, postorder):
            if len(postorder) == 0:
                return
            rootvalue = postorder[-1]
            root = TreeNode(rootvalue)
            if len(postorder) == 1:
                return root
            
            #找到root在inorder中的位置
            ind = inorder.index(rootvalue)
            left_in, right_in = inorder[:ind], inorder[ind+1:]
            
            #利用中序中分割出来的左右区间在后序中去分割
            left_out, right_out = postorder[:len(left_in)], postorder[len(left_in):len(left_in)+len(right_in)]
            #返回左右结点
            root.left = trace(left_in, left_out)
            root.right = trace(right_in, right_out)

            return root

        return trace(inorder, postorder)

总结

  1. 递归时返回什么?
    1. 如果需要搜索整棵二叉树且不用处理递归返回值,递归函数就不要返回值
    2. 如果需要搜索整棵二叉树且需要处理递归返回值,递归函数就需要返回值。
    3. 如果要搜索其中一条符合条件的路径,那么递归一定需要返回值,因为遇到符合条件的路径了就要及时返回。
  2. 一般需要搜索整棵树的时候,会用到递归的思想
  3. 构造二叉树必须有中序遍历的结果

         

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值