leetcode刷题记录:二叉树03(构造二叉树)

参考:https://labuladong.online/algo/data-structure/binary-tree-part2/

构造问题一般都是通过分解的思路,构造整棵树 = 根节点 + 构造左子树 + 构造右子树

654 最大二叉树

  1. 找到最大值和对应的index
  2. 先把根节点构造出来,然后递归地构造左子树和右子树
  3. 需要一个traverse函数,传入nums的索引,返回以nums[lo:hi]构造的最大二叉树。
class Solution(object):
    def constructMaximumBinaryTree(self, nums):
        """
        :type nums: List[int]
        :rtype: TreeNode
        """
        return self.traverse(nums, 0, len(nums)-1)
    def findMax(self, nums, lo, hi):
        res = nums[lo]
        for i in range(lo+1, hi+1):
            res = max(res, nums[i])
        return res, nums.index(res)
    def traverse(self, nums, lo, hi):
        if lo > hi:
            return
        # 找到数组中的最大值及其索引
        max_num, max_idx = self.findMax(nums, lo, hi)

        # 以最大值构造根节点
        root = TreeNode(max_num)

        # 递归调用构造左右子树
        root.left = self.traverse(nums, lo, max_idx-1)
        root.right = self.traverse(nums, max_idx+1, hi)
        return root

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

  • labuladong解法:
    框架:build函数,填6个参数,preStart,preEnd,inStart,inEnd要画图确定。

preStart = preStart + leftSize,leftSize = index - inStart,很重要

用全局map存index

class Solution(object):
    def buildTree(self, preorder, inorder):
        """
        :type preorder: List[int]
        :type inorder: List[int]
        :rtype: TreeNode
        """
        if (not preorder) or (not inorder)  or (len(preorder) != len(inorder)):
            return
        n = len(preorder)
        return self.traverse(preorder, 0, n-1, inorder, 0, n-1)
    def traverse(self, preorder, preLo, preHi, inorder, inLo, inHi):
        if preLo > preHi or inLo > inHi:
            return 
        rootValue = preorder[preLo] #1
        rootIndexInorder = inorder.index(rootValue) #2
        leftSize = rootIndexInorder - inLo # 2
        root = TreeNode(rootValue)
        root.left = self.traverse(preorder, preLo+1, preLo+leftSize, inorder, inLo, rootIndexInorder-1)
        root.right = self.traverse(preorder, preLo+leftSize+1, preHi, inorder, rootIndexInorder+1, inHi)
        return root

106 从中序和后序遍历恢复二叉树

思路类似,不再展开。注意:如果出现stackoverflow错误,一般是idx填错了,仔细检查一下。

class Solution(object):
    def buildTree(self, inorder, postorder):
        """
        :type inorder: List[int]
        :type postorder: List[int]
        :rtype: TreeNode
        """
        if (not inorder) or (not postorder) or (len(inorder)!=len(postorder)):
            return
        return self.traverse(inorder, 0, len(inorder)-1, postorder, 0, len(postorder)-1)

    def traverse(self, inorder, inLo, inHi, postorder, postLo, postHi):
        if (inLo > inHi) or (postLo > postHi):
            return
        rootValue = postorder[postHi] 
        rootIndexInorder = inorder.index(rootValue) 
        leftSize = rootIndexInorder - inLo 
        root = TreeNode(rootValue)
        root.left = self.traverse(inorder, inLo, rootIndexInorder-1, postorder, postLo, postLo+leftSize-1)
        root.right = self.traverse(inorder, rootIndexInorder+1, inHi, postorder, postLo+leftSize, postHi-1)
        return root

889 根据前序和后序遍历构造二叉树

首先明确一点,根据前序和后序遍历无法唯一确定一个二叉树。因为无法确定左右子树有哪些结点。和上面两题的区别有两点:

  1. build函数要讨论preStart=preEnd的情况
  2. build函数中要找左子树根节点,并返回其在postOrder中的位置,来构建索引。
class Solution(object):
    def constructFromPrePost(self, preorder, postorder):
        """
        :type preorder: List[int]
        :type postorder: List[int]
        :rtype: TreeNode
        """
        return self.traverse(preorder, 0, len(preorder)-1, postorder, 0, len(postorder)-1)
    def traverse(self, preorder, preLo, preHi, postorder, postLo, postHi):
        if (preLo > preHi) or (postLo > postHi):
            return
        if (preLo == preHi):
            return TreeNode(preorder[preLo])
        rootValue = preorder[preLo]
        root = TreeNode(rootValue)
        leftRootValue = preorder[preLo+1]
        leftRootIndexPostorder = postorder.index(leftRootValue)
        leftSize = leftRootIndexPostorder - postLo + 1
        root.left = self.traverse(preorder, preLo+1, preLo+leftSize, postorder, postLo, postLo+leftSize-1)
        root.right = self.traverse(preorder, preLo+leftSize+1, preHi, postorder, postLo+leftSize, postHi)
        return root

你可能感兴趣的:(2024算法工程师求职,leetcode,算法,职场和发展)