天梯赛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;
}