程式碼隨想錄演算法訓練營第17天 | 二叉樹04

哆啦**發表於2024-06-21

程式碼隨想錄演算法訓練營第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

相關文章