代码随想录学习Day 16

513.找树左下角的值

题目链接

讲解链接

注意树左下角的值指的是二叉树最底层最左边节点的值。所以使用层次遍历的方法比较简单,遍历每一层时都将该层的最左边节点的值保存下来,当遍历结束后将这个值返回即可。

class Solution:
    def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
        if not root:
            return None
        queue = deque([root])
        while queue:
            for i in range(len(queue)):
                node = queue.popleft()
                if i == 0:
                    result = node.val  # 记录当前层最左边节点的值
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return result

112.路径总和

题目链接

讲解链接

递归法:

1.递归函数参数及返回值:当前遍历节点以及一个计数器,返回值为bool型变量。

def traversal(self, cur, count):

2.递归终止条件:采用递减的方式,让计数器count初始为目标和,然后每次减去遍历路径节点上的数值。如果最后count == 0,同时到了叶子节点的话,说明找到了目标和。如果遍历到了叶子节点,count不为0,就是没找到。

if not cur.left and not cur.right:
    return True if result == 0 else False

3.单层递归逻辑:因为终止条件是判断叶子节点,所以递归的过程中不让空节点进入递归。递归函数是有返回值的,如果递归函数返回true,说明找到了合适的路径,应该立刻返回。

if cur.left:
    result -= cur.left.val
if self.traversal(cur.left, result):
    return True
result += cur.left.val
if cur.right:
    result -= cur.right.val
if self.traversal(cur.right, result):
    return True
result += cur.right.val
return False

 递归法完整代码:

class Solution:
    def traversal(self, cur, result):
        if not cur.left and not cur.right:
            return True if result == 0 else False
        if cur.left:
            result -= cur.left.val
            if self.traversal(cur.left, result):
                return True
            result += cur.left.val  # 回溯,将减去的值加回去
        if cur.right:
            result -= cur.right.val
            if self.traversal(cur.right, result):
                return True
            result += cur.right.val
        return False
        
    def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        if not root:
            return False
        return self.traversal(root, targetSum - root.val)
        

本题也可采用迭代法,使用层次遍历来求解:

class Solution:
    def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        if not root:
            return False
        queue = deque([root])
        path = deque([root.val])  # 用另一个队列来存储路径值,便于回退
        count = 0
        while queue:
            for _ in range(len(queue)):
                node = queue.popleft()
                count = path.popleft()
                if not node.left and not node.right:
                    if count == targetSum:
                        return True
                if node.left:
                    queue.append(node.left)
                    path.append(count + node.left.val)
                if node.right:
                    queue.append(node.right)
                    path.append(count + node.right.val)
        return False

 113.路经总和Ⅱ

题目链接

class Solution:
    def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
        result = []
        path = []
        self.traversal(root, targetSum, path, result)
        return result
    def traversal(self,node, count, path, result):
            if not node:
                return
            path.append(node.val)
            count -= node.val
            if not node.left and not node.right and count == 0:
                result.append(list(path))
            self.traversal(node.left, count, path, result)
            self.traversal(node.right, count, path, result)
            path.pop()

106.从中序与后序遍历序列构造二叉树 

题目链接

讲解链接

原理:以后序数组的最后一个元素为切割点,先切中序数组,根据中序数组,反过来再切后序数组。一层一层切下去,每次后序数组最后一个元素就是节点元素。

步骤:

1.若后序数组为0,返回空节点

2.后序数组的最后一个元素作为节点元素

3.在中序数组中寻找2.得到的节点元素作为切割点

4.切中序数组

5.切后序数组

6.递归处理左右区间

简而言之就是通过后序数组和中序数组来确定左右子树,进而切割得到左右子树的后序和中序数组,然后进行递归就能求出整个树。

class Solution:
    def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
        if not postorder:  # 树为空则返回null
            return None

        root_val = postorder[-1]  # 后序数组的最后一个值为根节点的值
        root = TreeNode(root_val)  # 创建根节点

        index = inorder.index(root_val)  # 查找根节点在中序数组中的位置

        left_inorder = inorder[:index]  # 切割中序数组,构建左中序数组,即为左子树
        right_inorder = inorder[index+1:]  # 切割中序数组,构建右中序数组,即为右子树

        left_postorder = postorder[:len(left_inorder)]  # 切割后序数组,注意左后序数组和左中序数组的长度是一样的
        right_postorder = postorder[len(left_inorder):len(postorder)-1]  # 切割后序数组

        root.left = self.buildTree(left_inorder, left_postorder)  # 递归得到左子树
        root.right = self.buildTree(right_inorder, right_postorder)  # 递归得到右子树

        return root  # 返回结果

 105.从前序与中序遍历序列构造二叉树

题目链接

本题思路与前一题基本一致,只需要将对后序数组的处理改为前序数组对应的处理即可。

class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
        if not preorder:
            return None
        root_val = preorder[0]
        root = TreeNode(root_val)
        index = inorder.index(root_val)
        left_inorder = inorder[:index]
        right_inorder = inorder[index+1:]
        # 注意中序数组的长度和前序数组一定是一样的
        left_preorder = preorder[1:1+len(left_inorder)]
        right_preorder = preorder[1+len(left_inorder):]
        root.left = self.buildTree(left_preorder, left_inorder)
        root.right = self.buildTree(right_preorder, right_inorder)
        return root
  • 15
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值