题目链接
题目描述
A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties:
- The left subtree of a node contains only nodes with keys less than the node's key.
- The right subtree of a node contains only nodes with keys greater than or equal to the node's key.
- Both the left and right subtrees must also be binary search trees.
If we swap the left and right subtrees of every node, then the resulting tree is called the Mirror Image of a BST.
Now given a sequence of integer keys, you are supposed to tell if it is the preorder traversal sequence of a BST or the mirror image of a BST.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤1000). Then N integer keys are given in the next line. All the numbers in a line are separated by a space.
Output Specification:
For each test case, first print in a line YES
if the sequence is the preorder traversal sequence of a BST or the mirror image of a BST, or NO
if not. Then if the answer is YES
, print in the next line the postorder traversal sequence of that tree. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line.
Sample Input 1:
7
8 6 5 7 10 8 11
结尾无空行
Sample Output 1:
YES
5 7 6 8 11 10 8
结尾无空行
Sample Input 2:
7
8 10 11 8 6 7 5
结尾无空行
Sample Output 2:
YES
11 8 10 7 5 6 8
结尾无空行
Sample Input 3:
7
8 6 8 5 10 9 11
结尾无空行
Sample Output 3:
NO
题目大意
确定一棵树为BST树,给出这个树的先序序列,判断这个先序序列是不是BST树或者BST镜像树的先序序列
如果是的话输出YES和后序序列
如果不是的话输出NO
解题思路
两种解法
第一种解法
根据给定的先序序列创建BST树,然后在遍历BST树和他的镜像树,看遍历出来的先序序列和初始给的序列是不是相等,如果相等的话就说明YES,不相等的话就输出NO
第二种解法
根据二叉搜索树的性质:
1.一棵二叉搜索树的左子树一定小于根节点,右子树一定大于根节点
2.推论,一棵二叉树左子树的最大值一定小于根节点,右子树的最小值一定大于根节点
3.在先序遍历中,满足:根节点,左子树,右子树的遍历方法,所以左子树的最大值是左子树最后遍历的数值,右子树的最小值是右子树第一个遍历的数值,所以左子树的最大值和右子树的最小值的下标应该是紧挨着相差1的
4.如果一棵树是平衡二叉树,那么他每一个子树的先序遍历的序列,从左到右第一个比根节点大的值的下标和从右向左第一个比根节点小的值的下标的差为一
5.这个条件为充要条件
例如有BST树
先序序列为
10 | 2 | 7 | 6 | 3 | 8 | 11 | 15 |
根据上面的性质有
int i=root+1,j=tail;
while(i<=tail&&pre[i]<pre[root]) i++;
while(j>root&&pre[j]>=pre[root]) j--;
找到的i,j对应为,相差为一
j | i | ||||||
10 | 2 | 7 | 6 | 3 | 8 | 11 | 15 |
题解
第一种解法
#include<bits/stdc++.h>
using namespace std;
struct Node{
struct Node *left;
struct Node *right;
int data;
};
typedef Node *List;
List insert(List root,int data){
if(root==NULL){
root=new Node();
root->left=NULL;
root->right=NULL;
root->data=data;
}
else if(data>=root->data){
root->right = insert(root->right,data);
}
else{
root->left = insert(root->left,data);
}
return root;
}
vector<int> v;
string s,r;
void dfs(List x){
if(x==NULL) return ;
s+=to_string(x->data);
dfs(x->left);
dfs(x->right);
v.push_back(x->data);
}
vector<int> v2;
void dfs2(List x){
if(x==NULL) return ;
r+=to_string(x->data);
dfs2(x->right);
dfs2(x->left);
v2.push_back(x->data);
}
int main(){
int n;
cin>>n;
List root=NULL;
List mroot=NULL;
string t;
for(int i=0;i<n;i++){
int data;
cin>>data;
t+=to_string(data);
root=insert(root,data);
}
int flag=0;
s.clear();
List root1=root;
dfs(root1);
if(s==t) flag=1;
r.clear();
dfs2(root);
if(r==t) flag=2;
if(flag==1){
cout<<"YES"<<endl;
for(int i=0;i<v.size();i++){
if(i!=0) cout<<" ";
cout<<v[i];
}
}
else if(flag==2){
cout<<"YES"<<endl;
for(int i=0;i<v2.size();i++){
if(i!=0) cout<<" ";
cout<<v2[i];
}
}
else{
cout<<"NO";
}
}
第二种解法
#include<bits/stdc++.h>
using namespace std;
int n;
bool f=false;
vector<int> pre;
vector<int> post;
void postOrder(int root,int tail){ //root为根节点,tail为最后一个节点
if(root>tail) return ;
int i=root+1,j=tail;
if(!f){ //BST树
while(i<=tail&&pre[i]<pre[root]) i++;
while(j>root&&pre[j]>=pre[root]) j--;
}
else{ //BST镜像树
while(i<=tail&&pre[i]>=pre[root]) i++;
while(j>root&&pre[j]<pre[root]) j--;
}
if(i-j!=1) return ; //当不满足BST树的条件时break;
postOrder(root+1,j);
postOrder(i,tail);
post.push_back(pre[root]);
}
int main(){
cin>>n;
pre.resize(n);
for(int i=0;i<n;i++){
cin>>pre[i];
}
postOrder(0,n-1);
if(post.size()!=n){ //当后序遍历的长度不等于树的所有节点个数的时候,说明不满足题意
post.clear();
f=true; //找镜像的
postOrder(0,n-1);
}
if(post.size()==n){
cout<<"YES"<<endl;
for(int i=0;i<post.size();i++){
if(i!=0) cout<<" ";
cout<<post[i];
}
}else{
cout<<"NO"<<endl;
}
}