Day 18 二叉树part05: 513.找树左下角的值 112. 路径总和 113.路径总和ii 106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树

112. 路径总和

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。

叶子节点 是指没有子节点的节点。

示例 1:

输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
输出:true
解释:等于目标和的根节点到叶节点路径如上图所示。

示例 2:

输入:root = [1,2,3], targetSum = 5
输出:false
解释:树中存在两条根节点到叶子节点的路径:
(1 --> 2): 和为 3
(1 --> 3): 和为 4
不存在 sum = 5 的根节点到叶子节点的路径。

示例 3:

输入:root = [], targetSum = 0
输出:false
解释:由于树是空的,所以不存在根节点到叶子节点的路径。

提示:

  • 树中节点的数目在范围 [0, 5000] 内
  • -1000 <= Node.val <= 1000
  • -1000 <= targetSum <= 1000
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def hasPathSum(self, root, targetSum):
        """
        :type root: TreeNode
        :type targetSum: int
        :rtype: bool
        注释之前: time: O(n)  space: O(n)
        注释之后: time: O(n)  space: O(h). h 是树的高度。
        """

        if root is None:
            return False

        # 栈用于深度优先遍历
        stack = [(root, root.val)]
        res = [] # 存储所有路径上所有节点值相加之和

        while stack:
            node, sum_val = stack.pop()

            # 如果是叶子节点,则得到最后的总和值
            if not node.left and not node.right:
                # res.append(sum_val)
                if sum_val == targetSum:
                    return True

            # 如果左子节点存在,更新总和值并入栈
            if node.left:
                stack.append((node.left, sum_val + node.left.val))
        
            # 如果右子节点存在,更新总和值并入栈
            if node.right:
                stack.append((node.right, sum_val + node.right.val))

        # return targetSum in res
        return False
            
            

113. 路径总和 II

给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。

叶子节点 是指没有子节点的节点。

示例 1:

输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:[[5,4,11,2],[5,8,4,5]]

示例 2:

输入:root = [1,2,3], targetSum = 5
输出:[]

示例 3:

输入:root = [1,2], targetSum = 0
输出:[]

提示:

  • 树中节点总数在范围 [0, 5000] 内
  • -1000 <= Node.val <= 1000
  • -1000 <= targetSum <= 1000
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def pathSum(self, root, targetSum):
        """
        :type root: TreeNode
        :type targetSum: int
        :rtype: List[List[int]]
        time:  O(n*log(n))
        space:  O(n^2) 
        """
        if not root:
            return []

        stack = [(root, [root.val])]
        res = [] # 存储最后所有 从根节点到叶子节点 路径总和等于给定目标和的路径。

        while stack:
            node, path = stack.pop()

            # 如果是叶子节点,判断路径总和等于给定目标
            if not node.left and not node.right:
                if sum(path) == targetSum:
                    res.append(path)
            
            # 如果有左叶子节点,更新路径
            if node.left:
                stack.append((node.left, path + [node.left.val]))

             # 如果有右叶子节点,更新路径
            if node.right:
                stack.append((node.right, path + [node.right.val]))

        return res
                


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

给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

示例 1:

输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
输出:[3,9,20,null,null,15,7]

示例 2:

输入:inorder = [-1], postorder = [-1]
输出:[-1]

提示:

  • 1 <= inorder.length <= 3000
  • postorder.length == inorder.length
  • -3000 <= inorder[i], postorder[i] <= 3000
  • inorder 和 postorder 都由 不同 的值组成
  • postorder 中每一个值都在 inorder 中
  • inorder 保证是树的中序遍历
  • postorder 保证是树的后序遍历

先切中序数组,再切前/后序数组

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def buildTree(self, inorder, postorder):
        """
        :type inorder: List[int]
        :type postorder: List[int]
        :rtype: TreeNode
        time: O(n^2)
        space: O(n)
        """

        # 特殊情况讨论: 树为空. (递归终止条件)
        if not inorder or not postorder:
            return None

        # 后序遍历的最后一个元素是根节点
        root_val = postorder.pop()
        root = TreeNode(root_val)

        # 在中序遍历中找到根节点的位置,这样我们就知道左右子树的节点数了
        idx = inorder.index(root_val)

        # 计算左子树的大小
        left_size = idx

        # 构建左子树和右子树
        # 注意我们如何切分postorder
        root.left = self.buildTree(inorder[:idx], postorder[:left_size])
        root.right = self.buildTree(inorder[idx+1:], postorder[left_size:])

        return root

此函数的核心思路是:

  1. 从后序遍历中取出最后一个元素,即为当前的根。
  2. 在中序遍历中找到该元素的位置,将数组分为两部分,一部分是左子树的所有元素,另一部分是右子树的所有元素。
  3. 递归地对左子树和右子树进行上述操作。

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

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

示例 1:

输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
输出: [3,9,20,null,null,15,7]

示例 2:

输入: preorder = [-1], inorder = [-1]
输出: [-1]

提示:

  • 1 <= preorder.length <= 3000
  • inorder.length == preorder.length
  • -3000 <= preorder[i], inorder[i] <= 3000
  • preorder 和 inorder 均 无重复 元素
  • inorder 均出现在 preorder
  • preorder 保证 为二叉树的前序遍历序列
  • inorder 保证 为二叉树的中序遍历序列

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def buildTree(self, preorder, inorder):
        """
        :type preorder: List[int]
        :type inorder: List[int]
        :rtype: TreeNode
        time: O(N^2)
        space: O(N)
        """

        if not preorder or not inorder:
            return None

        # 前序遍历的第一个元素是根节点
        root_val = preorder.pop(0)
        root = TreeNode(root_val)

        # 在中序遍历中找到根节点的位置,这样我们就知道左右子树的节点数了
        idx = inorder.index(root_val)

        # 计算左子树的大小
        left_size = idx

        # 构建左子树和右子树
        # 注意我们如何切分preorder
        root.left = self.buildTree(preorder[:left_size], inorder[:idx])
        root.right = self.buildTree(preorder[left_size:], inorder[idx+1:])

        return root


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值