代码随想录算法训练营第十八天|513.找树左下角的值,112. 113 路径总和,106. 105 构造二叉树

513.找树左下角的值

LeetCode - The World's Leading Online Programming Learning Platform

思路:本题要找出二叉树最下面一层最左边的值, 一眼看过去就是用层序遍历。 每一层的循环从左往右,开头的元素记录下来, 最后输出最后一层开头元素。 

难点: 无

class Solution:
    def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
        q = deque([root])
        ans = None
        while q:
            l = len(q)
            for i in range(l):
                cur_node = q.popleft()
                if i == 0:
                    ans = cur_node.val
                if cur_node.left: q.append(cur_node.left)
                if cur_node.right: q.append(cur_node.right)
        return ans

112. 路径总和

LeetCode - The World's Leading Online Programming Learning Platform

思路: 本题涉及到回溯算法,在从 root 到 leaf 访问每个节点的时候要记录走过路径的值。 采用迭代法时, 就是从root 开始, 向左右两个subtree 找是否有 路径到leaf,路径和为 targetSum - root.val  (除去root值,新的targetSum)的值。 一直找下去, 如果到 leaf 的值等于 到它的时候的新targetSum, 输出True, 否则输出False。 如果左右两个有任何一个是 True, 那结果输出True。 

难点:理解迭代的终止条件和输出。

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

113. 路径总和II

LeetCode - The World's Leading Online Programming Learning Platform

思路: 和上一题类似, 但是要求输出的所有root-leaf sum = target sum 的路径, 所以回溯起来会比上一题难。 如果迭代的话,可以考虑增加一个走过路径的 input, 如果碰到leaf, sum(path) + leaf.val == target sum 就吧 path.append(leaf.val 放入output list 中). 不过这里我试用了递归法。 stack 中放入 tuple ( cur_node, path, sum) 这种结构。 

难点: 需要理清楚需要track 的是啥。 

class Solution:
    def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
        ans = []
        if not root:
            return ans
        st = deque()
        st.append((root, 0, []))
        while st:
            cur_node, cur_sum, path = st.pop()
            cur_sum += cur_node.val
            path.append(cur_node.val)
            if (not (cur_node.left or cur_node.right)) and cur_sum == targetSum: # leaf and get tarSum
                ans.append(path)
            if cur_node.right:
                st.append((cur_node.right, cur_sum, path.copy()))
            if cur_node.left:
                st.append((cur_node.left, cur_sum, path.copy()))
        return ans

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

LeetCode - The World's Leading Online Programming Learning Platform

思路:首先如果只有一个值的时候, 直接输出一个 treenode 就可以了。 然后后序遍历中root的值是位于最后一位的。 然后在中序列表中找到相应位置i, 那么 0 - i-1 的值是root 右边的, i+1 之后的值是root 右边的。 同样把后序列表也一拆二。 然后分别长左右两边的subtree。 

难点: 弄得中序和后序遍历元素的顺序

class Solution:
    def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
        if len(inorder) == 1:
            return TreeNode(inorder[0])
        node = TreeNode(postorder[-1])
        pos = inorder.index(node.val)
        if pos!=0:
            left_inorder = inorder[:pos]
            left_postorder = postorder[:pos]
            node.left = self.buildTree(left_inorder, left_postorder)
        if pos!=len(inorder) - 1:
            right_inorder = inorder[pos+1:]
            right_postorder = postorder[pos:-1]
            node.right = self.buildTree(right_inorder, right_postorder)
        return node

 

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

LeetCode - The World's Leading Online Programming Learning Platform

思路: 和上题一摸一样

class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
        if len(inorder) == 1:
            return TreeNode(inorder[0])
        node = TreeNode(preorder[0])
        pos = inorder.index(node.val)
        if pos!=0:
            left_inorder = inorder[:pos]
            left_preorder = preorder[1:pos+1]
            node.left = self.buildTree(left_preorder, left_inorder)
        if pos!=len(inorder) - 1:
            right_inorder = inorder[pos+1:]
            right_preorder = preorder[pos+1:]
            node.right = self.buildTree(right_preorder, right_inorder)
        return node
        

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值