day16 513.找树左下角的值 112.路径总和 113.路径综合 || 106.从中序与后序遍历序列构造二叉树

513. 找树左下角的值

给定一个二叉树,在树的最后一行找到最左边的值。

示例 1:

513.找树左下角的值

示例 2:

513.找树左下角的值1

第一种方法(递归法-只要保证优先左边搜索,无中间节点的处理逻辑):

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:

        maxDepth = 0
        result = 0
        def traversal(node, depth):
            nonlocal maxDepth, result
            if not node.left and not node.right:
                if depth > maxDepth:
                    result = node.val
                    maxDepth = depth

            if node.left:
                depth += 1
                traversal(node.left, depth)
                depth -= 1
            if node.right:
                depth += 1
                traversal(node.right, depth)
                depth -= 1

            return result

        return traversal(root, 1)

第二种方法(层序遍历-借助队列):

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:

        que = collections.deque([root]) # 转化为数组才能传入队列
        result = 0

        while que:

            for i in range(len(que)):
                node = que.popleft()
                if i == 0:
                    result = node.val
                if node.left:
                    que.append(node.left)
                if node.right:
                    que.append(node.right)
            
        return result

112. 路径总和 

给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。

说明: 叶子节点是指没有子节点的节点。

示例: 给定如下二叉树,以及目标和 sum = 22,

返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。

第一种方法(递归法):

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        if root:
            if not root.left and not root.right and root.val == targetSum:
                return True
            elif not root.left and not root.right and root.val != targetSum:
                return False
            targetSum -= root.val
        
        
        def traversal(node, count):
            
            if node:
                if not node.left and not node.right:
                   
                    if count == 0:
                        return True
                    if count != 0:
                        return False
                
                if node.left:
                    count -= node.left.val
                    if traversal(node.left, count):
                        return True
                    count += node.left.val
                if node.right:
                    count -= node.right.val
                    if traversal(node.right, count):
                        return True
                    count += node.right.val
            
            return False

        
        return traversal(root, targetSum)

113. 路径总和 II

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

说明: 叶子节点是指没有子节点的节点。

示例: 给定如下二叉树,以及目标和 sum = 22,

113.路径总和ii1.png

第一种方法(递归法): 

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def __init__(self):
        self.result = []
        self.path = []

    def traversal(self, cur, count):
        if not cur:
            return

        if not cur.left and not cur.right and count == 0: # 遇到了叶子节点且找到了和为sum的有效路径
            self.result.append(self.path[:])
            return

        if not cur.left and not cur.right: # 遇到叶子节点而没有找到合适的边,直接返回
            return

        if cur.left: # 左 (空节点不遍历)
            self.path.append(cur.left.val)
            count -= cur.left.val
            self.traversal(cur.left, count) # 递归
            count += cur.left.val # 回溯
            self.path.pop() # 回溯

        if cur.right: #  右 (空节点不遍历)
            self.path.append(cur.right.val) 
            count -= cur.right.val
            self.traversal(cur.right, count) # 递归
            count += cur.right.val # 回溯
            self.path.pop() # 回溯

        return

    def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
        self.result.clear()
        self.path.clear()
        if not root:
            return self.result
        self.path.append(root.val) # 把根节点放进路径
        self.traversal(root, targetSum - root.val)
        return self.result 

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

 根据一棵树的中序遍历与后序遍历构造二叉树。

注意: 你可以假设树中没有重复的元素。

例如,给出

  • 中序遍历 inorder = [9,3,15,20,7]
  • 后序遍历 postorder = [9,15,7,20,3] 返回如下的二叉树:

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

第一种方法(递归法):

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:

        # 后序数组为空,终止
        if not postorder:
            return

        # 后序数组最后一个元素为当前中间节点元素
        root_val = postorder[-1]
        root = TreeNode(root_val)

        # 如果后序数组只剩一个元素,说明是叶子节点,返回节点给上个节点左或右孩子
        if len(postorder) == 1:
            return root
            
        # 找切割点
        separator_idx = inorder.index(root_val)

        # 切割中序数组
        inorder_left = inorder[:separator_idx]
        inorder_right = inorder[separator_idx + 1:]
        
        # 切割后序数组(左中序数组和左后序数组大小相等)
        postorder_left = postorder[:len(inorder_left)]
        postorder_right = postorder[len(inorder_left):len(postorder) - 1]

        # 递归
        root.left = self.buildTree(inorder_left, postorder_left)
        root.right = self.buildTree(inorder_right, postorder_right)
        
        return root

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值