第五章 树 4 AcWing 1527. 判断二叉搜索树
原题链接
算法标签
树的遍历
思路
二叉搜索树的中序遍历为递增序列,若根据前序遍历序列和排序后的前序遍历(即中序序列)可构造出一棵二叉搜索树或根据镜像(逆序后的中序序列)可以构造出一棵二叉搜索树,则满足条件,输出后序遍历序列。
由于树中节点权值不唯一, 寻找前序遍历中某节点在中序遍历中位置时, 若在中序遍历有多个值与寻找值一致, 选择哪一个
举例如下
根据题意
对于原树:只有选择中序遍历中第一个8作为根节点(中序遍历时从前向后遍历), 才能保证左子树上所有结点的值均小于它的根结点的值
对于镜像树:只有选择中序遍历中第二个8作为根节点(中序遍历时从后向前遍历), 才能保证左子树上所有结点的值均小于它的根结点的值
代码
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define int long long
#define x first
#define y second
#define ump unordered_map
#define pq priority_queue
#define rep(i, a, b) for(int i=a;i<b;++i)
#define Rep(i, a, b) for(int i=a;i>=b;--i)
#define rep1(i, a, b) for(i=a;i<b;++i)
#define Rep1(i, a, b) for(i=a;i>=b;--i)
using namespace std;
typedef pair<int, int> PII;
const int N = 1005;
//int t, n, m, cnt, ans;
int pre[N], in[N], post[N], q[N], cnt;
int n;
// ump<int, int> l, r, pos;
inline int rd(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
void put(int x) {
if(x<0) putchar('-'),x=-x;
if(x>=10) put(x/10);
putchar(x%10^48);
}
int build(int il, int ir, int pl, int pr, int type){
// 当前区间无元素 构建成功
if(il>ir){
return true;
}
// 根节点即前序遍历的第一个点
int root=pre[pl];
int k;
// 若是原树
if(!type){
// 根节点在中序遍历中的位置
rep1(k, il, ir+1){
if(in[k]==root){
break;
}
}
// 无法找到根节点在中序遍历中的位置 构建失败
if(k>ir){
return false;
}
}else{ // 若是镜像树
// 根节点在中序遍历中的位置
Rep1(k, ir, il){
if(in[k]==root){
break;
}
}
// 无法找到根节点在中序遍历中的位置 构建失败
if(k<il){
return false;
}
}
bool res=true;
// 左子树是否可以构建
if(!build(il, k-1, pl+1, pl+1+(k-1- il), type)){
res=false;
}
// 右子树是否可以构建
if(!build(k+1, ir, pl+1+(k-1-il)+1, pr, type)){
res=false;
}
// 将当前根节点存储至后序遍历序列
post[cnt++]=root;
return res;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
n=rd();
rep(i, 0, n){
pre[i]=rd();
in[i]=pre[i];
}
sort(in, in+n);
if(build(0, n-1, 0, n-1, 0)){
puts("YES");
printf("%lld", post[0]);
rep(i, 1, n){
printf(" %lld", post[i]);
}
puts("");
}else{
reverse(in, in+n);
cnt=0;
if(build(0, n-1, 0, n-1, 1)){
puts("YES");
printf("%lld", post[0]);
rep(i, 1, n){
printf(" %lld", post[i]);
}
puts("");
}else{
puts("NO");
}
}
return 0;
}
原创不易
转载请标明出处
如果对你有所帮助 别忘啦点赞支持哈