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

题目链接:leetcode

思路:虽然是二叉树的题目,但是更多的还是分治的思想
对于给定的前序遍历preorder和中序遍历inorder,首先我们不难发现,这棵树的根结点其实就是preorder[0]。同时知道preorder[0]在inorder中一定也存在,不妨设preorder[0]==inorder[k]。

由于inorder是中序遍历,所以k左边的就是根节点左子树的中序遍历、k右边的就是根节点右子树的中序遍历。

通过中序遍历我们知道左子树的长度,不妨设为l,我们可以知道preorder从1到l+1就是根节点左子树的前序遍历,剩下的最后一部分就是根节点右子树的前序遍历。

也就是说,我们可以计算出左子树、右子树的前序遍历和中序遍历,从而可以用分治的思想,将规模较大的问题分解成为两个较小的问题,然后递归的进行处理,还原左子树和右子树,最后连通根节点一起组成一棵完整的树。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None

class Solution(object):
def buildTree(self, preorder, inorder):
"""
:type preorder: List[int]
:type inorder: List[int]
:rtype: TreeNode
"""
def dfs(preorder,inorder,pl,pr,il,ir):
if pl>pr:return None
root = TreeNode(preorder[pl])
for i in range(il,ir+1):
if preorder[pl] == inorder[i]:
break
root.left = dfs(preorder,inorder,pl+1,pl+1+(i-1-il),il,i-1)
root.right = dfs(preorder,inorder,pl+1+(i-1-il)+1,pr,i+1,ir)
return root
res = dfs(preorder,inorder,0,len(preorder)-1,0,len(inorder)-1)
return res