参考:https://labuladong.online/algo/data-structure/binary-tree-part2/
构造问题一般都是通过分解的思路,构造整棵树 = 根节点 + 构造左子树 + 构造右子树
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
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
思路类似,不再展开。注意:如果出现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
首先明确一点,根据前序和后序遍历无法唯一确定一个二叉树。因为无法确定左右子树有哪些结点。和上面两题的区别有两点:
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