day16 第六章 二叉树 part04

找树左下角的值

前序法

class Solution:
    max_depth = 0
    result = 0
    def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
        Solution.max_depth = 0
        Solution.result = root.val

        self.bottomValue(root, 1, Solution.result)
        return Solution.result

    def bottomValue(self, node: Optional[TreeNode], depth: int, result: int) -> None:
        # 前序
        # 退出条件
        if not node.left and not node.right:
            if depth > Solution.max_depth:
                Solution.max_depth = depth
                Solution.result = node.val
            return
        
        # 左右
        if node.left:
            self.bottomValue(node.left, depth+1, Solution.result)

        if node.right:
            self.bottomValue(node.right, depth+1, Solution.result)

层序

class Solution:
    def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
        # 层序遍历
        # if not root:
        #     return
        
        q = collections.deque()
        q.append(root)
        result = []
        while q:
            size = len(q)
            level = []
            for _ in range(size):
                node = q.popleft()
                level.append(node.val)
                if node.left:
                    q.append(node.left)
                if node.right:
                    q.append(node.right)
        result.append(level[0])
        return result[-1]
        

路径总和 ​​​​​​​

判断函数是否需要返回值:

如果需要处理返回值,函数必须要有返回值。

如果不用处理返回值,函数不需要有返回值。

返回值:return + value

如果遍历整棵树,return都不需要,更不用说value了;

如果中断,那需要return,需不需要value看具体情况。

112.路径总和

深度优先

tips:

两个function名字很像的时候别写错了!

# 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 not root:
            return False
        return self.pathSum(root, targetSum-root.val)

    def pathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        
        if not root.left and not root.right and targetSum == 0:
            return True

        if root.left:
            targetSum -= root.left.val
            if self.pathSum(root.left, targetSum):
                return True
            targetSum += root.left.val

        if root.right:
            targetSum -= root.right.val
            if self.pathSum(root.right, targetSum):
                return True
            targetSum += root.right.val

        return False

113. 路径总和 II

class Solution:
    def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
        # 前序
        if not root:
            return []
            
        result = []
        path = []

        path.append(root.val)
        self.findPath(root, targetSum - root.val, path, result)
        return result

    def findPath(self, node: Optional[TreeNode], targetSum: int, path: List[int], result: List[List[int]]) -> None:
        if not node.left and not node.right:
            if targetSum == 0:
                result.append(list(path)) # list is mutable. So before appending it to result, make a copy.
            return

        if node.left:
            path.append(node.left.val)
            targetSum -= node.left.val
            self.findPath(node.left, targetSum, path, result)
            targetSum += node.left.val
            path.pop()
        
        if node.right:
            path.append(node.right.val)
            targetSum -= node.right.val
            self.findPath(node.right, targetSum, path, result)
            targetSum += node.right.val
            path.pop()

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

# 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 len(inorder) == 0:
            return None
        root = self.traversal(inorder, 0, len(inorder), postorder, 0, len(postorder))
        return root


    def traversal(self, inorder: List[int], inorder_start: int, inorder_end: int, postorder: List[int], postorder_start: int, postorder_end: int) -> Optional[TreeNode]:
        # 前序 [)
        # if inorder_end == 0:
        #     return None
        if inorder_start == inorder_end:
            return None

        # postorder找root
        root = TreeNode(val=postorder[postorder_end-1])

        if inorder_start == inorder_end-1:
            return root


        # 用root分隔inorder
        delimeter = 0
        for i in range(inorder_start, inorder_end):
            if inorder[i] == root.val:
                delimeter = i
                break
        inorder_left_start = inorder_start
        inorder_left_end = delimeter
        inorder_right_start = delimeter + 1
        inorder_right_end = inorder_end

        # 用inorder分割postorder
        postorder_left_start = postorder_start
        postorder_left_end = postorder_start + inorder_left_end - inorder_left_start
        postorder_right_start = postorder_left_end
        postorder_right_end = postorder_right_start + inorder_right_end - inorder_right_start

        # 继续循环
        root.left = self.traversal(inorder, inorder_left_start, inorder_left_end, postorder, postorder_left_start, postorder_left_end)
        root.right = self.traversal(inorder, inorder_right_start, inorder_right_end, postorder, postorder_right_start, postorder_right_end)
        return root

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

# 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, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
        if len(preorder) == 0:
            return None
        return self.traversal(preorder, 0, len(preorder), inorder, 0, len(inorder))
        

    def traversal(self, preorder: List[int], preorder_start: int, preorder_end: int, inorder: List[int], inorder_start: int, inorder_end: int) -> Optional[TreeNode]:
        # [)
        if preorder_end == preorder_start:
            return None
        
        root = TreeNode(val = preorder[preorder_start])

        if preorder_end == preorder_start + 1:
            return root

        # find delimiter to split inorder
        for i in range(inorder_start, inorder_end):
            if inorder[i] == root.val:
                delimiter = i
                break
        
        inorder_left_start = inorder_start
        inorder_left_end = delimiter
        inorder_right_start = delimiter + 1
        inorder_right_end = inorder_end

        preorder_left_start = preorder_start + 1
        preorder_left_end = preorder_left_start + inorder_left_end - inorder_left_start
        preorder_right_start = preorder_left_end
        preorder_right_end = preorder_end

        root.left = self.traversal(preorder, preorder_left_start, preorder_left_end, inorder, inorder_left_start, inorder_left_end)
        root.right = self.traversal(preorder, preorder_right_start, preorder_right_end, inorder, inorder_right_start, inorder_right_end)
        return root

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值