解题思路:主要是有镜像存在,那就运行两次就行了,第一次是左子树小于根,第二次是左子树大于根
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int a[1009],cnt,rt;
struct node
{
int l,r,v;
}s[1009];
int build(int l,int r)
{
if(l>r) return -1;
int p=a[l],k=l+1,k2;
while(k<=r&&a[k]<p) k++;
k2=k;
while(k2<=r&&a[k2]>=p) k2++;
if(k2!=r+1) return 0;
int rt1=build(l+1,k-1);
int rt2=build(k,r);
if(!rt1) return 0;
if(!rt2) return 0;
s[cnt].l=rt1;
s[cnt].r=rt2;
s[cnt].v=p;
return cnt++;
}
int build_m(int l,int r)
{
if(l>r) return -1;
int p=a[l],k=l+1,k2;
while(k<=r&&a[k]>=p) k++;
k2=k;
while(k2<=r&&a[k2]<p) k2++;
if(k2!=r+1) return 0;
int rt1=build_m(l+1,k-1);
int rt2=build_m(k,r);
if(!rt1) return 0;
if(!rt2) return 0;
s[cnt].l=rt1;
s[cnt].r=rt2;
s[cnt].v=p;
return cnt++;
}
void af(int u)
{
if(s[u].l!=-1)
af(s[u].l);
if(s[u].r!=-1)
af(s[u].r);
if(u!=rt)
printf("%d ",s[u].v);
}
int main()
{
//freopen("t.txt","r",stdin);
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
cnt=1;
rt=build(0,n-1);
if(rt)
{
printf("YES\n");
af(rt);
printf("%d",s[rt].v);
return 0;
}
cnt=1;
rt=build_m(0,n-1);
if(rt)
{
printf("YES\n");
af(rt);
printf("%d",s[rt].v);
return 0;
}
printf("NO\n");
return 0;
}