代码随想录算法训练营第17天 | 二叉树04

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

找树左下角的值
https://leetcode.cn/problems/find-bottom-left-tree-value/
找树左下角的值代码随想录
https://leetcode.cn/problems/find-bottom-left-tree-value/
路径总和
https://leetcode.cn/problems/path-sum/description/
路径总和2
https://leetcode.cn/problems/path-sum-ii/description/
路径总和代码随想录
https://programmercarl.com/0112.路径总和.html#思路
106.从中序与后序遍历序列构造二叉树
https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/description/
106.从中序与后序遍历序列构造二叉树
https://programmercarl.com/0106.从中序与后序遍历序列构造二叉树.html#思路

找树左下角的值

给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。

假设二叉树中至少有一个节点。

题解重点

  • 递归法:先遍历curr.left 才是左下角;
  • 迭代法:层序遍历法非常轻松
class Solution:
    def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
        if not root:
            return root
        self.depth = float('-inf')
        self.res = root.val
        self.trans(root,0)
        return self.res

    def trans(self,curr,depth):
        if not curr.right and not curr.left:
            if depth>self.depth:
                self.depth = depth
                self.res = curr.val
                return 
        if curr.left:
            depth = depth+1
            self.trans(curr.left,depth)
            depth = depth-1
        if curr.right:
            depth = depth+1
            self.trans(curr.right,depth)
            depth = depth-1

层序遍历迭代法

class Solution:
    def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
        if not root:
            return None
        res = []
        queue = collections.deque([root])
        while queue:
            line = []
            for i in range(len(queue)):
                curr = queue.popleft()
                line.append(curr.val)
                if curr.left:
                    queue.append(curr.left)
                if curr.right:
                    queue.append(curr.right)
            res.append(line)
        return res[-1][0]

路径总和

题目1:路径总和1

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

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

题解重点

  • 递归法: 1.复杂法:准确传递 targetsum和value 不需要回溯;2.简约法:调用原函数即可
  • 迭代法:栈里内存(node,val_sum)

题解代码

复杂递归法

class Solution:
    def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        if not root:
            return False
        if self.trans(root,targetSum,0):
            return True
        else:
            return False

    def trans(self,curr,targetSum,value):
        value = value+curr.val
        if not curr.right and not curr.left:
            if value==targetSum:
                return True
            else:
                return False
        if curr.left:
            if self.trans(curr.left,targetSum,value):
                return True
            # value = value - curr.left.val
        if curr.right:
            if self.trans(curr.right,targetSum,value):
                return True
            # value = value - curr.right.val

简约递归法

class Solution:
    def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        if not root:
            return False
        if not root.left and not root.right and targetSum==root.val:
            return True
        return self.hasPathSum(root.left,targetSum-root.val) or self.hasPathSum(root.right,targetSum-root.val)

迭代法

class Solution:
    def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        if not root:
            return False
        st = [root]
        res_st = [root.val]
        while st:
            curr = st.pop()
            res_i = res_st.pop()
            if curr:
                if curr.right:
                    st.append(curr.right)
                    res_st.append(res_i+curr.right.val)

                if curr.left:
                    st.append(curr.left)
                    res_st.append(res_i+curr.left.val)
                st.append(curr)
                st.append(None)
                res_st.append(res_i)
                res_st.append(None)
            else:
                node = st.pop()
                res = res_st.pop()
                if not node.left and not node.right:
                    if res==targetSum:
                        return True
        return False

路径总和2

题目

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

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

题解重点:同上题

题解代码:

class Solution:
    def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
        self.res = []
        path = []
        if not root:
            return self.res
        self.trans(root,path,targetSum)
        return self.res

    def trans(self,curr,path,targetSum):
        path.append(curr.val)
        if not curr.left and not curr.right:
            if sum(path)==targetSum:
                self.res.append(path[:])
                return
        if curr.left:
            self.trans(curr.left,path,targetSum)
            path.pop()
        if curr.right:
            self.trans(curr.right,path,targetSum)
            path.pop()
class Solution:
    def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
        if not root:
            return []
        res = [] ##最终结果存放
        st = [(root,[root.val])] ##遍历点
        while st:
            curr,path_i = st.pop()
            if curr:
                if curr.right:
                    st.append((curr.right,path_i+[curr.right.val]))
                if curr.left:
                    st.append((curr.left,path_i+[curr.left.val]))
                st.append((curr,path_i))
                st.append((None,None))
            else:
                node,path_i = st.pop()
                if not node.right and not node.left:
                    if sum(path_i)==targetSum:
                        res.append(path_i)
        return res

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

题目

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

题解重点

  • 流程步骤:
    1.判断后序数列是否为空;为空说明没有根节点,返回根节点;
    2.如果不为空,最后一个节点为根节点;
    3.找到根节点在中序序列的位置;
    4.切割中序列;
    5.切割后序列;
    6.递归处理左子树和右子树;

题解代码

class Solution:
    def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
        if not postorder:
            return None
        root = TreeNode(postorder[-1])
        cut_point_1 = inorder.index(root.val)
        # print(f"cut_point{cut_point_1}")
        in_left,in_right = inorder[:cut_point_1],inorder[cut_point_1+1:]
        # print(f"in_left:{in_left},in_right:{in_right}")
        pos_left,pos_right = postorder[:len(in_left)],postorder[len(in_left):-1]
        # print(f"pos_left:{pos_left},pos_right:{pos_right}")
        root.left = self.buildTree(in_left,pos_left)
        root.right = self.buildTree(in_right,pos_right)
        return root
posted @ 2024-06-21 11:14  哆啦**  阅读(5)  评论(0编辑  收藏  举报