PTA L2-004 这是二叉搜索树吗?-判断是否是对一棵二叉搜索树或其镜像进行前序遍历的结果 团体程序设计天梯赛-练习集

时间:2020-12-19 23:42:33

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

  • 其左子树中所有结点的键值小于该结点的键值;
  • 其右子树中所有结点的键值大于等于该结点的键值;
  • 其左右子树都是二叉搜索树。

所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树。

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

输入格式:

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

输出格式:

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

输入样例 1:

7
8 6 5 7 10 8 11

输出样例 1:

YES
5 7 6 8 11 10 8

输入样例 2:

7
8 10 11 8 6 7 5

输出样例 2:

YES
11 8 10 7 5 6 8

输入样例 3:

7
8 6 8 5 10 9 11

输出样例 3:

NO

 

因为前面写了二叉树的,所以这道题打算也用那种思路,写是写出来了,但是感觉怪怪的。

我建树是保存的下标编号,因为数可能是一样的,但是下标编号是唯一的。

建完树之后,写了个bfs搜了一下左右节点,发现好像也没毛病,但是自己想的一个样例过不了,肯定是错的代码,应该是后台样例比较水,所以满分水过了。。。

PTA L2-004 这是二叉搜索树吗?-判断是否是对一棵二叉搜索树或其镜像进行前序遍历的结果 团体程序设计天梯赛-练习集

代码写的奇丑无比,但是还是希望有好心人能帮我想想我的代码哪里要改才能改对,过不了的样例:

2

2 1

输出应该为

YES

1 2

我的代码跑不出来。

后面看了一下别人的题解,发现还是别人的思路更简洁好实现一些,学到了,我这个弟弟。

 

先贴一下我的代码,不要学我的代码,有bug的,找不出来什么问题。。。

代码:

  1 //L2-004 这是二叉搜索树吗?
  2 #include<bits/stdc++.h>
  3 using namespace std;
  4 typedef long long ll;
  5 const int maxn=1e5+10;
  6 const int inf=0x3f3f3f3f;
  7 
  8 int pre[maxn];
  9 int n,flag=0;
 10 
 11 struct node{
 12     int l,r;
 13 }tree[maxn];
 14 
 15 int buildmin(int l,int r)
 16 {
 17     if(l>r) return 0;
 18     if(r==-1) return 0;
 19     int rt=pre[l];
 20     int p1=r;
 21     while(pre[p1]>=rt){
 22         if(p1==l) break;
 23         p1--;
 24     }
 25     int minn=inf,pos;
 26     for(int i=p1;i>l;i--){
 27         if(minn>pre[i]){
 28             minn=pre[i];
 29             pos=i;
 30         }
 31     }
 32     for(int i=pos;i>l;i--){
 33         if(pre[i]>=rt){
 34             flag=1;break;
 35         }
 36     }
 37     if(flag==1){
 38         buildmin(0,-1);
 39     }
 40 //    cout<<pre[p1]<<endl;
 41     else{
 42         if(p1!=l){
 43             tree[l].l=buildmin(l+1,p1);
 44             tree[l].r=buildmin(p1+1,r);
 45         }
 46         else{
 47            tree[l].r=buildmin(p1+1,r);
 48         }
 49         return l;
 50     }
 51 }
 52 
 53 int buildmax(int l,int r)
 54 {
 55     if(l>r) return 0;
 56     if(r==-1) return 0;
 57     int rt=pre[l];
 58     int p1=r;
 59     while(pre[p1]<rt){
 60         p1--;
 61     }
 62     for(int i=p1;i>l;i--){
 63         if(pre[i]<rt){
 64             flag=1;break;
 65         }
 66     }
 67     if(flag==1){
 68         buildmax(0,-1);
 69     }
 70 //    cout<<pre[p1]<<endl;
 71     else{
 72         if(p1!=r){
 73             tree[l].l=buildmax(l+1,p1);
 74             tree[l].r=buildmax(p1+1,r);
 75         }
 76         else{
 77             tree[l].l=buildmax(l+1,p1);
 78         }
 79         return l;
 80     }
 81 }
 82 
 83 void bfs(int x)
 84 {
 85     vector<int> vec;
 86     queue<int> que;
 87     que.push(x);
 88     while(!que.empty()){
 89         int ret=que.front();
 90         que.pop();
 91         if(ret==0) break;
 92         vec.push_back(ret);
 93         if(tree[ret].l!=0){
 94             que.push(tree[ret].l);
 95         }
 96         if(tree[ret].r!=0){
 97             que.push(tree[ret].r);
 98         }
 99     }
100     int l=vec.size();
101     for(int i=0;i<l;i++)
102         cout<<pre[vec[i]]<<" ";
103     cout<<endl;
104 }
105 
106 vector<int> vec;
107 
108 int behorder(int x)
109 {
110     if(tree[x].l==0&&tree[x].r==0){
111         if(pre[x]!=0)
112             vec.push_back(pre[x]);
113         return 0;
114     }
115     behorder(tree[x].l);
116     behorder(tree[x].r);
117     vec.push_back(pre[x]);
118 }
119 
120 void print()
121 {
122     int l=vec.size();
123     for(int i=0;i<l-1;i++)
124         cout<<vec[i]<<" ";
125     cout<<vec[l-1]<<endl;
126 }
127 
128 int main()
129 {
130     scanf("%d",&n);
131     for(int i=1;i<=n;i++)
132         scanf("%d",&pre[i]);
133 //        cout<<"23333333333"<<endl;
134     if(pre[2]<pre[1]){
135         buildmin(1,n);
136         if(flag==1) cout<<"NO"<<endl;
137         else{
138 //            bfs(1);
139             cout<<"YES"<<endl;
140             behorder(1);
141             print();
142         }
143     }
144     else{
145         buildmax(1,n);
146         if(flag==1) cout<<"NO"<<endl;
147         else{
148 //            bfs(1);
149             cout<<"YES"<<endl;
150             behorder(1);
151             print();
152         }
153     }
154 //    for(int i=1;i<=n;i++)
155 //        cout<<tree[i].l<<" "<<tree[i].r<<endl;
156 //
157 ////    else buildmax(1,n);
158 //    behorder();
159 
160 }

 

 

学的别人的思路:

代码:

 1 //L2-004 这是二叉搜索树吗?
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 typedef long long ll;
 5 const int maxn=1e5+10;
 6 const int inf=0x3f3f3f3f;
 7 
 8 int n;
 9 int isMirror=0;
10 int pre[maxn];
11 vector<int> vec;
12 
13 int build(int l,int r)
14 {
15     if(l>r) return 0;
16     int rt=pre[l];
17     int p1=l+1,p2=r;
18     if(!isMirror){
19         while(p1<=r&&rt>pre[p1]) p1++;
20         while(p2>l&&rt<=pre[p2]) p2--;
21     }
22     else{
23         while(p1<=r&&rt<=pre[p1]) p1++;
24         while(p2>l&&rt>pre[p2]) p2--;
25     }
26     if(p1-p2!=1) return 0;
27     build(l+1,p2);//按照后序遍历建树
28     build(p1,r);
29     vec.push_back(rt);
30 }
31 
32 int main()
33 {

 

 

先这样。