PAT (Advanced Level) 1020 Tree Traversals (分治+二叉树的一维数组表示)

版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}

猜你喜欢

转载自blog.csdn.net/w419387229/article/details/81631802