版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/w419387229/article/details/81631802
虽然过了,但是如果数据再变态点,比如30个全是右子树,数组就不够用了,一开始也没想到,但交了之后,最后一个case段错误,才意识到,可能层数会很多,那就需要数组长度很长,最后开到1e5,幸运得过了。
思路就是通过后序和中序来把后序的那串左右一直划分(分治),当前划分的这个基准点就可以得知应该所在的位置。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
int n, MAX = 100000;
int post[35];
int iner[35];
int tree[100000];
void dfs(int prePos, int left, int right, int flag){
int pos = prePos*2+flag;
tree[pos] = post[right];
if(left >= right)
return;
if(flag == 1){//right
if(iner[post[right]] - iner[tree[prePos]] - 1 < right - left){
int sub = right - left - iner[post[right]] + iner[tree[prePos]] + 1;
dfs(pos,right-sub,right-1,1);
}
if(iner[post[right]] - iner[tree[prePos]] > 1){
int sub = iner[post[right]] - iner[tree[prePos]] - 1;
dfs(pos,left,left+sub-1,0);
}
}
else{
if(iner[tree[prePos]] - iner[post[right]] > 1){
int sub = iner[tree[prePos]] - iner[post[right]] - 1;
dfs(pos,right-sub,right-1,1);
}
if(iner[tree[prePos]] - iner[post[right]] - 1 < right - left){
int sub = right - left - iner[tree[prePos]] + iner[post[right]] + 1;
dfs(pos,left,left+sub-1,0);
}
}
}
int main(){
cin >> n;
for(int i = 1; i <= n; i++){
scanf("%d",&post[i]);
}
for(int i = 1; i <= n; i++){
int pos;
scanf("%d",&pos);
iner[pos] = i;
}
tree[1] = post[n];
if(iner[post[n]] < n)//right sub
dfs(1,iner[post[n]],n-1,1);
if(iner[post[n]] > 1)
dfs(1,1,iner[post[n]]-1,0);
int flag = 0;
for(int i = 1; i < MAX; i++){
if(tree[i]){
if(flag == 0){
flag = 1;
printf("%d",tree[i]);
}
else
printf(" %d",tree[i]);
}
}
return 0;
}