【力扣-二叉树】12、从中序与后序遍历序列构造二叉树(106

「这是我参与11月更文挑战的第18天,活动详情查看:2021最后一次更文挑战

106. 从中序与后序遍历序列构造二叉树

题目描述

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

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

例如,给出

1
2
ini复制代码中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]

返回如下的二叉树:

1
2
3
4
5
markdown复制代码    3
/ \
9 20
/ \
15 7

解析

递归法

  • 步骤:
    • 1、判断数组大小是否为0,为0则表示空节点
    • 2、不为空,取后序遍历数组的最后一个元素(作为根节点)
    • 3、在中序遍历中找到后序遍历的最后一个元素
    • 4、切割中序数组,将中序数组分为中序左数组,中序右数组
    • 5、切割后序数组,得到后序左数组,后序右数组
    • 6、递归处理左区间和右区间

代码

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
c++复制代码class Solution
{
public:
TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder)
{
return traversal(inorder, postorder);
}

private:
TreeNode *traversal(vector<int> &inorder, vector<int> &postorder)
{
// 1、判断数组大小是否为0,为0则表示空节点,直接返回空
if (inorder.size() == 0)
{
return NULL;
}
// 取后序遍历的最后一个元素作为根节点
int rootVal = postorder[postorder.size() - 1];
// 设置根节点
TreeNode *root = new TreeNode(rootVal);
int splitPos;
// 3、查找中序遍历的分割点
for (splitPos = 0; splitPos < inorder.size(); splitPos++)
{
if (inorder[splitPos] == rootVal)
{
break;
}
}

// 4、切割中序数组,分为左数组和右数组
vector<int> inLeft(inorder.begin(), inorder.begin() + splitPos);
vector<int> inRight(inorder.begin() + splitPos + 1, inorder.end());

// 5、切割后序数组

// 首先舍去最后一个元素
postorder.resize(postorder.size() - 1);
// 后序数组的切割根据已有条件来获得
// 后序左数组的大小与中序左数组的大小相同,以此来找到切割点
vector<int> postLeft(postorder.begin(), postorder.begin() + inLeft.size());
vector<int> postRight(postorder.begin() + inLeft.size(), postorder.end());

// 6、递归处理左区间和右区间
root->left = traversal(inLeft, postLeft);
root->right = traversal(inRight, postRight);

return root;
}
};

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%