Keshawn_lu's Blog

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

字数统计: 574阅读时长: 2 min
2020/05/22 Share

题目简介:

根据一棵树的前序遍历与中序遍历构造二叉树。

注意:
你可以假设树中没有重复的元素。

例如,给出

1
2
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]

返回如下的二叉树:

1
2
3
4
5
  3
/ \
9 20
/ \
15 7

思路:

我们就按下面这个例子来讲解一下思路。

1
2
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
  1. 首先我们根据前序遍历知道它的第一个结点3便是根节点,再去遍历中序遍历,从而知道根节点在中序遍历的位置。

  2. 知道了根节点在中序遍历中的位置后,我们便能知道这棵树的左子树为[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]

  3. 再利用递归,将根节点的左子树和右子树看成一颗新的树(同样拥有根节点和它们的左右子树)。得到左子树的根节点为9,右子树的根节点为20,再分别构造新的pre_left, pre_right, in_left, in_right

    • 左子树只有根节点9了,结束递归。
    • 右子树:pre_left = [15], pre_right = [7], in_left = [15], in_right = [7]
  4. 第二次递归,新的左右子树都只有一个结点,分别作为新的子树的根节点后结束递归。

  5. 最后返回根节点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
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
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]);
}

//j = 0 时为根节点,得从1开始
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;

}
};
CATALOG
  1. 1. 题目简介:
  2. 2. 思路:
  3. 3. 代码如下: