假设二叉树上各结点的权值互不相同且都为正整数。
给定二叉树的前序遍历和中序遍历,请你输出二叉树的后序遍历的第一个数字。
输入格式
第一行包含整数 NN,表示二叉树结点总数。
第二行给出二叉树的前序遍历序列。
第三行给出二叉树的中序遍历序列。
输出格式
输出二叉树的后序遍历的第一个数字。
数据范围
1≤N≤500001≤N≤50000
输入样例:
7
1 2 3 4 5 6 7
2 3 1 5 4 7 6
输出样例:
3
算法步骤
1.首先由前序遍历序列和中序遍历序列重建树
a.前序序列的第一个数为根,
b.在中序序列中找到根的位置(用unordered_map 提前记录中序序列)
c.确定之后就可以得到左子树|右子树 的大小 及 在前序遍历序列和中序遍历序列中的具体位置
d.分别建立左子树和右子树
2.后序遍历一遍建好的树
C++ 代码
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std;
const int N = 50010;
int pre_[N];
int in_[N];
unordered_map<int, int> index;
int n;
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int _v):val(_v), left(nullptr), right(nullptr){};
~TreeNode(){};
};// ; important!!!
TreeNode* buildtree(int* _pre, int* _in, int preL, int preR, int inL,int inR){
if(preL>preR) return nullptr;
int rootvalue = _pre[preL];
int k = index[rootvalue] - inL;//the number of left treenode (Dont forget minus inL!!!)
TreeNode* root = new TreeNode(rootvalue);
root->left = buildtree(_pre,_in,preL+1,preL+k,inL,inL+k-1);
root->right = buildtree(_pre,_in,preL+k+1,preR,inL+k+1,inR);
return root;
}
void postorder(TreeNode* root, vector<int>& _vec){
if(!root) return;
postorder(root->left,_vec);
postorder(root->right,_vec);
_vec.push_back(root->val);
}
int main(){
cin >> n;
for(int i = 0; i < n; i++){
cin >> pre_[i];
}
for(int i = 0; i < n; i++){
cin >> in_[i];
index[in_[i]] = i;
}
TreeNode* r = buildtree(pre_,in_,0,n-1,0,n-1);
vector<int> post;
postorder(r,post);
cout << post.front();
return 0;
}