GPLT L2-004 这是二叉搜索树吗?

题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805070971912192

类似题目有FBI树

这两个题有个小技巧,就是建树时是前序遍历,只要将输出放在递归调用之后就是后序遍历了,仔细思考下就能够想明白

对前中后序不熟的记住前中后都是形容跟的次序,左永远在右的前面

建树的时候注意左子树遍历时有i<=r,右子树却只是j>l而没有等号,那是因为可能一个序列只有左子树,所以左子树遍历必须包括所有,而有右子树就肯定有左子树了,就不需要包含了,另外仔细读题,

二叉搜索树的等于号是在右子树(镜像就是左子树)

一开始设不是镜像跑一次,向量大小不为n就清空在按照是镜像跑一次

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int inf=1<<30;
 4 typedef long long ll;
 5 typedef pair<int,int> P;
 6 const double pi=acos(-1);
 7 const int mod=1e8+7;
 8 const int maxn=1007;
 9 const int maxm=6300;
10 int a[maxn];
11 bool is_mirror;
12 vector<int> v;
13 void maketree(int l,int r){
14     if(l>r) return ;
15     int i=l+1,j=r;//因为是前序遍历,开头第一个是根,此时i在左子树,j在右子树 
16     if(!is_mirror){
17         while(i<=r&&a[l]>a[i]) i++;//非镜像左子树都比根小,循环结束把左子树遍历完后i跑到右子树的第一个 
18         while(j>l&&a[j]>=a[l]) j--;
19     }else{
20         while(i<=r&&a[l]<=a[i]) i++;
21         while(j>l&&a[j]<a[l]) j--;
22     }
23     if(i-j!=1) return ;
24     maketree(l+1,j);//左子树 
25     maketree(i,r);//右子树 
26     v.push_back(a[l]);//按照前序建树,递归后在输出就是后序了,可以仔细想想,类似题有FBI树 
27 }
28 int main(){
29     int n;scanf("%d",&n);
30     for(int i=0;i<n;i++)scanf("%d",&a[i]);
31     maketree(0,n-1);
32     if(v.size()!=n){
33         is_mirror=1;
34         v.clear();
35         maketree(0,n-1);
36     }
37     if(v.size()==n){
38         printf("YES
%d",v[0]);
39         for(int i=1;i<n;i++)printf(" %d",v[i]);
40         cout<<endl;
41     }else{
42         printf("NO
");
43     }
44     return 0;
45 }
原文地址:https://www.cnblogs.com/qingjiuling/p/10485445.html