题解
- 根据前序/后序 和 中序 遍历结果,我们都可以还原这颗二叉树,因为前序(根左右),中序(左根右),后序(左右根),我们根据树根所在的位置,就可以得出树的左右儿子,只要递归处理,我们就可以还原整颗树 ,注意的是区间的边界问题,可以直接列出数字来确定,这样不容易出错
- 当建树完成后,我们只需要从根节点进行BFS就可以实现层序遍历
代码
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<unordered_map>
#include<queue>
using namespace std;
const int N = 35;
int n, x;
vector<int> inorder, postorder;
unordered_map<int, int> mp;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {
}
};
TreeNode *dfs(int il, int ir, int pl, int pr) {
if (pl > pr) return NULL;
int k = mp[postorder[pr]];
TreeNode *root = new TreeNode(inorder[k]);
root->left = dfs(il, k - 1, pl, pl + k - il - 1);
root->right = dfs(k + 1, ir, pl + k - il, pr - 1);
return root;
}
TreeNode *buildTree() {
for (int i = 0; i < n; i++) {
mp[inorder[i]] = i;
}
return dfs(0, n - 1, 0, n - 1);
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
cin >> n;
for (int i = 0; i < n; i++) {
cin >> x;
postorder.push_back(x);
}
for (int i = 0; i < n; i++) {
cin >> x;
inorder.push_back(x);
}
TreeNode *root = buildTree();
queue<TreeNode> q;
q.push(*root);
vector<int> res;
while (q.size()) {
auto t = q.front();
q.pop();
res.push_back(t.val);
if (t.left != nullptr) q.push(*t.left);
if (t.right != nullptr) q.push(*t.right);
}
for (int i = 0; i < n; i++) {
if (i != n - 1) {
cout << res[i] << " ";
} else {
cout << res[i] << endl;
}
}
return 0;
}