PAT 1167 Cartesian Tree 代码顶好理解的解法
原题链接
求解方法
1. 先找到最小的值即为根结点
2. 递归左右子树每次找区间内最小的结点作为根结点
3. bfs找出层序遍历
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=40;
int n,in[N];
unordered_map<int,int> l,r,pos;
int get_min(int il,int ir){ // 找到中序序列从l到r中的最小值
int minn=2147483647;
for(int i=il;i<=ir;i++) minn=min(minn,in[i]);
return minn;
}
int build(int il,int ir){ // 建树
int root=get_min(il,ir);
int k=pos[root];
if(il<k) l[root]=build(il,k-1);
if(k<ir) r[root]=build(k+1,ir);
return root;
}
void bfs(int root){ // bfs找层序遍历序列
int hh=0,tt=0,q[N];
q[0]=root;
while(hh<=tt){
int k=q[hh++];
if(l.count(k)) q[++tt]=l[k];
if(r.count(k)) q[++tt]=r[k];
}
cout<<q[0];
for(int i=1;i<n;i++) cout<<' '<<q[i];
}
signed main(){
cin>>n;
for(int i=0;i<n;i++) cin>>in[i],pos[in[i]]=i;
build(0,n-1);
int root=get_min(0,n-1);
bfs(root);
return 0;
}