106从中序与后序遍历序列构造二叉树
题目: 根据一棵树的中序遍历与后序遍历构造二叉树.
来源: https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/
法一: 模仿105方法
思路: index设置为全局变量,依次从后序遍历中取一个元素,用该元素来分割中序遍历list.确定每次递归的左子树和右子树.优点是用到内存小,每次当left==right时,说明左子树或右子树为空了,返回None.
# Definition for a binary tree node. class TreeNode: def __init__(self, x): self.val = x self.left = None self.right = None # 执行用时 :60 ms, 在所有 python3 提交中击败了98.47% 的用户 # 内存消耗 :17.1 MB, 在所有 python3 提交中击败了96.25%的用户 from typing import List class Solution: def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode: # 这里反序的目的是为了模仿105中的方法,前序是中左右,后序是左右中,反序后即为中右左 postorder.reverse() index = 0 def recursion(left=0,right=len(inorder)): # 这里实际上将index设置成了全局变量 nonlocal index if left == right: return None root_val = postorder[index] root = TreeNode(root_val) k = index_map[root_val] index += 1 # 这里的关键是确定递归的范围,要通过写例子来确定 root.right = recursion( left=k+1, right=right) root.left = recursion( left, right= k) return root index_map = {element:index for index,element in enumerate(inorder)} return recursion() if __name__ == '__main__': duixiang = Solution() # inorder = [8, 4, 9, 2, 10, 5, 1, 6, 3, 13, 11, 14, 7, 12] # postorder = [8, 9, 4, 10, 5, 2, 6, 13, 14, 11, 12, 7, 3, 1] inorder = [1,2] postorder = [2,1] a = duixiang.buildTree(inorder=inorder, postorder=postorder) print(a)
法二: 模仿889方法
思路: 仍然是每次从后序遍历中取第一个元素,不同的是后序遍历的list每次都不同,每次都是用切片传list.缺点是内存消耗大.
# Definition for a binary tree node. class TreeNode: def __init__(self, x): self.val = x self.left = None self.right = None # 执行用时 :220 ms, 在所有 python3 提交中击败了50.63% 的用户 # 内存消耗 :87.3 MB, 在所有 python3 提交中击败了72.50%的用户 # 这个方法模仿889从前序和后序遍历构造二叉树 class Solution: def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode: postorder.reverse() def recursion(inorder=inorder, postorder=postorder): # 有可能某个节点的左子树或右子树为空,直接返回None if len(inorder) == 0: return None root = TreeNode(postorder[0]) # 如果长度为1了,说明其没有左子树和右子树了,直接返回 if len(postorder) == 1: return root # 求节点在中序遍历中的索引 L = inorder.index(root.val) size = len(inorder) # 这里的关键是确定递归的范围,要通过写例子来确定 root.right = recursion( inorder[L+1:], postorder[1:size-L]) root.left = recursion( inorder[:L], postorder[-L:]) return root return recursion() if __name__ == '__main__': duixiang = Solution() # inorder = [8, 4, 9, 2, 10, 5, 1, 6, 3, 13, 11, 14, 7, 12] # postorder = [8, 9, 4, 10, 5, 2, 6, 13, 14, 11, 12, 7, 3, 1] inorder = [1,2] postorder = [2,1] a = duixiang.buildTree(inorder=inorder, postorder=postorder) print(a)