天梯赛L2-004

天梯赛L2-004

  • 一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点,

    其左子树中所有结点的键值小于该结点的键值;
    其右子树中所有结点的键值大于等于该结点的键值;
    其左右子树都是二叉搜索树。
    所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树。

    给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果。

    输入格式:
    输入的第一行给出正整数 N(≤1000)。随后一行给出 N 个整数键值,其间以空格分隔。

    输出格式:
    如果输入序列是对一棵二叉搜索树或其镜像进行前序遍历的结果,则首先在一行中输出 YES ,然后在下一行输出该树后序遍历的结果。数字间有 1 个空格,一行的首尾不得有多余空格。若答案是否,则输出 NO。

二叉搜索树,前序遍历第一个数为根,从左向右搜索比根的值小的最后一个节点,记为i;从右向左搜索比根的值大的第一个节点,记为j,当且仅当j-i=1时是二叉搜索树

#include<bits/stdc++.h>
using namespace std;
int n,sum=0,a[1005],tr[1005],sl[1005],sr[1005];
bool vis=0;
bool build1(int l,int r){
    
    
	tr[++sum]=a[l];
	if(l==r) return 1;
	int x=l,y=r+1,k=sum;
	while(x+1<=n&&a[l]>a[x+1]) x++;
	while(y-1>l&&a[y-1]>=a[l]) y--;
	if(x!=y-1) return 0;
	if(x>l){
    
    
		sl[k]=l+1;
		if(!build1(l+1,x)) return 0;
	}
	if(y<=r){
    
    
		sr[k]=y;
		if(!build1(y,r)) return 0;
	}
	return 1;
}
bool build2(int l,int r){
    
    
	tr[++sum]=a[l];
	if(l==r) return 1;
	int x=l,y=r+1,k=sum;
	while(x+1<=n&&a[l]<=a[x+1]) x++;
	while(y-1>l&&a[y-1]<a[l]) y--; 
	if(x!=y-1) return 0;
	if(x>l){
    
    
		sl[k]=l+1;
		if(!build2(l+1,x)) return 0;
	}
	if(y<=r){
    
    
		sr[k]=y;
		if(!build2(y,r)) return 0;
	}
	return 1;
}
void print(int fa){
    
    
	if(!fa) return;
	print(sl[fa]);
	print(sr[fa]);
	if(vis) cout<<" ";
	else vis=1;
	cout<<tr[fa];
}
int main(){
    
    
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	if(build1(1,n)){
    
    
		cout<<"YES"<<endl;
		print(1);
		return 0;
	}
	sum=0;
	memset(tr,0,sizeof(tr));
	memset(sl,0,sizeof(sl));
	memset(sr,0,sizeof(sr));
	if(build2(1,n)){
    
    
		cout<<"YES"<<endl;
		print(1);
		return 0;
	}
	cout<<"NO";
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/u013455437/article/details/109240273