题目简介:
根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
1 2
| 前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = [9,3,15,20,7]
|
返回如下的二叉树:
思路:
我们就按下面这个例子来讲解一下思路。
1 2
| 前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = [9,3,15,20,7]
|
首先我们根据前序遍历知道它的第一个结点3
便是根节点,再去遍历中序遍历,从而知道根节点在中序遍历的位置。
知道了根节点在中序遍历中的位置后,我们便能知道这棵树的左子树为[9]
,右子树为[15,20,7]
。将这些数字按照在前序遍历和中序遍历的位置存到pre_left, pre_right, in_left, in_right
中。
即pre_left = [9], pre_right = [20,15,7], in_left = [9], in_right = [15, 20, 7]
。
再利用递归,将根节点的左子树和右子树看成一颗新的树(同样拥有根节点和它们的左右子树)。得到左子树的根节点为9
,右子树的根节点为20
,再分别构造新的pre_left, pre_right, in_left, in_right
。
- 左子树只有根节点
9
了,结束递归。
- 右子树:
pre_left = [15], pre_right = [7], in_left = [15], in_right = [7]
第二次递归,新的左右子树都只有一个结点,分别作为新的子树的根节点后结束递归。
最后返回根节点root
即可。
代码如下:
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
|
class Solution { public: TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
int size = preorder.size(); if(size == 0) return NULL; TreeNode* root = new TreeNode(preorder[0]);
vector<int> pre_left, pre_right, in_left, in_right;
int i; for(i = 0; i < size; i++){
if(preorder[0] == inorder[i]) break; in_left.push_back(inorder[i]); }
for(i = i + 1; i < size; i++){
in_right.push_back(inorder[i]); }
for(int j = 1; j < size; j++){
if(j <= in_left.size()) pre_left.push_back(preorder[j]); else pre_right.push_back(preorder[j]); }
root -> left = buildTree(pre_left, in_left); root -> right = buildTree(pre_right, in_right);
return root; } };
|