pta L2-004 这是二叉搜索树吗

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

评价:应用很灵活,难点在于怎么处理镜像,在根本上还是考了二叉搜索树的性质;

题目思路:

题目可以这么做,我们拿到第一个样例分析,

7

8 6 5 7 10 8 11

 

 这很典型,根节点的键值大于左子树的键值,同时小于右子树的键值;

我们就可以这样分析了,从根节点的下一个节点出发,挨个遍历,一直找到比根节点的键值的大的节点,就停止了,同时,这也确定了左子树的范围;

另外,从右边界出发,向root位置靠拢,一直找到比根节点键值小的节点,就确定了右子树的范围,

那镜像呢?

镜像则是反过来处理,左边界是找比根节点键值小的节点,右边界同理;

另外在开始的时候判断root的位置和right的位置是否合法,在判断遍历完以后左边界的右边在减去1是否等于右边界的左边

然后在从检查从根的下一个带左边界的右边,右边界的左边到右边;

最后把根节点每次都压入last数组,表示每次压入的都是根节点,就确定了后序序列;

同时

在主函数中判断last的个数是不是等于n,如果等于n就证明是BST,因为节点全被压进去了;

不是就证明在check中出现了不合法性,就不是bst了

那说了这么多,镜像究竟是怎么处理的呢?

我们引入一个bool判断,如果这个last个数不等于n就不是bst

 

 我们先清last数组为0,然后置bool变量为true(开始的时候是false),然后对应check函数中的对于镜像的遍历;

在判断last的长度,如果是,就正常输出了,如果不是,输出no就ok啦

 

 

Talk is cheap. Show me the code.

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n;
 4 bool flag;
 5 vector<int>a,last;
 6 void check(int root,int right)
 7 {
 8     if(root>right)//判断合法性 
 9     return ;
10     int i=root+1;//从下一个开始,因为根节点已被确定 
11     int j=right;//边界 
12     if(!flag)//非镜像 
13     {
14         while(i<=right&&a[root]>a[i])
15         i++;
16         while(j>root&&a[j]>=a[root])//题目说右子树小于等于 
17         j--;
18     }
19     else//镜像 
20     {
21         while(i<=right&&a[root]<=a[i])//置左右子树相反 
22         i++;
23         while(j>root&&a[j]<a[root])
24         j--;
25     }
26     if(i-1!=j)
27     return ;//合法性 
28     check(root+1,j);//j其实就是右子树的左边界,在这范围内也就是遍历左子树 
29     check(i,right);//同理 
30     last.push_back(a[root]);//有后序遍历的味道了 
31 }
32 int main()
33 {
34     cin>>n;
35     for(register int i=0;i<n;i++)
36     {
37         int x;
38         cin>>x;
39         a.push_back(x);//先序序列 
40     }
41     check(0,n-1);//从root到right的检查 
42     if(last.size()!=n)//如果是镜像 
43     {
44         last.clear();
45         flag=1;//置为镜像,对应check中的检查方式 
46         check(0,n-1);    
47     } 
48     if(last.size()==n)//是的话就说明是BST 
49     {
50         printf("YES\n");
51         for(register int i=0;i<n;i++)
52         {
53             printf("%d",last[i]);
54             if(i<n-1)
55             printf(" ");
56         }
57     }
58     else
59     cout<<"NO";
60     return 0;    
61 }

i,j的位置如图所示

 

posted @ 2022-04-20 17:21  江上舟摇  阅读(63)  评论(0)    收藏  举报