###105. Construct Binary Tree from Preorder and Inorder Traversal 题目: 难度 : Medium preorder 是 根 -> 左 -> 右 inorder 是 左 -> 根 -> 右 首先pre的第一个就是整个树的root, 假设 pre[0] = in[k],那么in的前k-1个就是树的左子树,后面部分就是树的右子树,这样递归来看. 然后递归来看,对于前k-1个又是同样的道理吧。 然后用递归,写了一颗小树测试,感觉上是对的, ``` class TreeNode(object): def __init__(self, x): self.val = x self.left = None self.right = None nodeA = TreeNode('A') nodeB = TreeNode('B') nodeC = TreeNode('C') nodeD = TreeNode('D') nodeE = TreeNode('E') nodeF = TreeNode('F') nodeA.left = nodeB nodeA.right = nodeC nodeB.left = nodeD nodeB.right = nodeE nodeC.left = nodeF # A # / \ # B C # / \ / # D E F def construct(preorder, inorder): if preorder == inorder == []: return None else: rootVal = preorder[0] root = TreeNode(rootVal) k = inorder.index(rootVal) if len(preorder) == len(inorder) == 1: return root else: root.left = construct(preorder[1:1+k],inorder[:k]) root.right = construct(preorder[k+1:],inorder[k+1:]) return root root = construct(['A','B','D','E','C','F'],['D','B','E','A','F','C']) ``` 尝试AC发现,memory limit超,用大一点的数据测试RecursionError: maximum recursion depth exceeded。 根据网上的参考改成偏iteration一点的递归, AC通过 mark一下,为了避免数组的复杂操作,这里直接用左右界和数组的引用来代表一段前序遍历和中序遍历。直接用递归更改list本身不能AC,但是变成这样就可以AC,因为更改数组会拷贝数组带来很多内存和递归上的麻烦,是这样的么? 这个技巧还比较常见,就是用原本list的角标,而不去cut list本身 ``` class Solution(object): def buildTree(self, preorder, inorder): """ :type preorder: List[int] :type inorder: List[int] :rtype: TreeNode """ def buildTree(preorder, inorder, lp, rp, li, ri): if lp > rp or li > ri: return None root = TreeNode(preorder[lp]) k = inorder.index(preorder[lp]) # left node left = buildTree(preorder, inorder, lp+1, lp + k - li, li, k - 1) right = buildTree(preorder, inorder, lp + k - li + 1, rp, k+1, ri) root.left = left root.right = right return root return buildTree(preorder, inorder, 0 , len(preorder) - 1, 0, len(inorder) -1) ```