代码随想录算法训练营第16天

10 阅读3分钟

513.找树左下角的值

# 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.max_depth=0
        self.depth=0
        self.res=0
    def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
        self.traverse(root)
        return self.res
    def traverse(self,root):
        if not root:
            return 
        self.depth+=1
        if self.depth>self.max_depth:
            self.max_depth=self.depth
            self.res=root.val
        self.traverse(root.left)
        self.traverse(root.right)
        self.depth-=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
from collections import deque
class Solution:
    def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 
        q=deque()
        q.append(root)
        result=0
        while q:
            sz=len(q)
            for i in range(sz):
                node=q.popleft()
                if i==0:
                    result=node.val
                if node.left:
                    q.append(node.left)
                if node.right:
                    q.append(node.right)
        return result

112.路径总和

# 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.cnt=0
        self.flag=False
    def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        self.traverse(root,targetSum)
        return self.flag
    def traverse(self,root,targetSum):
        if not root:
            return False
        self.cnt+=root.val
        if not root.left and not root.right:
            if self.cnt == targetSum:
                self.flag=True
        self.traverse(root.left,targetSum)
        self.traverse(root.right,targetSum)
        self.cnt-=root.val
        

113.路径总和Ⅱ

# 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.cnt=0
        self.res=[]
        self.path=[] 
    def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
        self.traverse(root,targetSum)
        return self.res
    def traverse(self,root,targetSum):
        if not root:
            return 
        self.cnt+=root.val
        self.path.append(root.val)
        if not root.left and not root.right:
            if self.cnt==targetSum:
                self.res.append(list(self.path))
        
        self.traverse(root.left, targetSum)
        if root.left:  # 只有存在子节点时才需要回溯
            self.cnt -= root.left.val
            self.path.pop()
        
        self.traverse(root.right, targetSum)
        if root.right:  # 只有存在子节点时才需要回溯
            self.cnt -= root.right.val
            self.path.pop()

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

思路:

  • 如果数组大小为0的话,说明是空节点
  • 如果不为空,那么取后序数组最后一个元素作为节点元素
  • 找到后序数组最后一个元素在中序数组的位置,作为切割点
  • 切割中序数组,切成中序左数组和中序右数组
  • 切割后序数组,切成后序左数组和后序右数组
  • 递归处理左区间和右区间
class Solution:
    def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
        # 第一步: 特殊情况讨论: 树为空. (递归终止条件)
        if not postorder:
            return None

        # 第二步: 后序遍历的最后一个就是当前的中间节点.
        root_val = postorder[-1]
        root = TreeNode(root_val)

        # 第三步: 找切割点.
        separator_idx = inorder.index(root_val)

        # 第四步: 切割inorder数组. 得到inorder数组的左,右半边.
        inorder_left = inorder[:separator_idx]
        inorder_right = inorder[separator_idx + 1:]

        # 第五步: 切割postorder数组. 得到postorder数组的左,右半边.
        #重点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

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

仿照106题的思路:

  • 如果数组大小为0的话,说明是空节点
  • 如果不为空,那么取前序数组第一个元素作为节点元素
  • 找到前序数组第一个元素在中序数组的位置,作为切割点
  • 切割中序数组,切成中序左数组和中序右数组
  • 切割前序数组,切成前序左数组和前序右数组
  • 递归处理左区间和右区间
# 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
"""
仿照106题的思路:
* 如果数组大小为0的话,说明是空节点
* 如果不为空,那么取前序数组第一个元素作为节点元素
* 找到前序数组第一个元素在中序数组的位置,作为切割点
* 切割中序数组,切成中序左数组和中序右数组
* 切割前序数组,切成前序左数组和前序右数组
* 递归处理左区间和右区间
"""
class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
        if not preorder:
            return None
        root_Value=preorder[0]
        root=TreeNode(root_Value)
        separate_idx=inorder.index(root_Value)  #第三步
        #切割中序数组
        inorder_left=inorder[:separate_idx]
        inorder_right=inorder[separate_idx+1:]
        #切割前序数组
        preorder_left=preorder[1:1+len(inorder_left)]
        preorder_right=preorder[1+len(inorder_left):]

        root.left=self.buildTree(preorder_left,inorder_left)
        root.right=self.buildTree(preorder_right,inorder_right)

        return root