。。。天梯模擬賽沒寫出樹的遍歷。。。補幾道類似的題
L2-004 這是二叉搜索樹嗎?
鏈接:https://pintia.cn/problem-sets/994805046380707840/problems/994805070971912192
思路:先核對這串序列是否符合先序遍歷,如果不符合再核對下是否符合鏡像后的,因為題目要求給出樹的后序遍歷,所以每次核對的時候都按照后序遍歷存點。
實現代碼:
#include<bits/stdc++.h> using namespace std; vector<int>v; int a[1010],is; void dfs(int l,int r){ if(l > r) return ; int tr = l+1; int tl = r; if(!is){ while(tr <= r&&a[tr] < a[l]) tr++; while(tl > l&&a[tl] >= a[l]) tl--; } else{ while(tr <= r&&a[tr] >= a[l]) tr++; while(tl > l&&a[tl] < a[l]) tl--; } if(tr - tl != 1) return ; dfs(l+1,tl); dfs(tr,r); v.push_back(a[l]); } int main() { int n; cin>>n; for(int i = 0;i < n;i ++){ cin>>a[i]; } dfs(0,n-1); if(v.size()!=n){ is = 1; v.clear(); dfs(0,n-1); } if(v.size() != n) cout<<"NO"<<endl; else{ cout<<"YES"<<endl; for(int i = 0;i < n;i ++){ cout<<v[i]; if(i != n-1) cout<<" "; } cout<<endl; } }
L2-006 樹的遍歷
鏈接:https://pintia.cn/problem-sets/994805046380707840/problems/994805069361299456
思路:后序遍歷最后一個點是根,我們得到這個根,在中序遍歷上找到這個根的位置p,可以以此推出左子樹的大小為p-l1,這樣兩個序的左右子樹的區間都可以被找到,保存下當前根節點左右子節點的值,然后用bfs跑出層次遍歷的序列。
實現代碼:
#include<bits/stdc++.h> using namespace std; const int M = 1e3+10; int post_order[M],in_order[M],lch[M],rch[M],n; int build(int l1,int r1,int l2,int r2){ if(l1 > r1) return 0; int rt = post_order[r2]; int p = l1; while(in_order[p]!=rt) p++; int cnt = p-l1; lch[rt] = build(l1,p-1,l2,l2+cnt-1); rch[rt] = build(p+1,r1,l2+cnt,r2-1); return rt; } void bfs() { queue<int>q; vector<int>v; q.push(build(0,n-1,0,n-1)); while(!q.empty()){ int cur = q.front(); q.pop(); v.push_back(cur); if(lch[cur]) q.push(lch[cur]); if(rch[cur]) q.push(rch[cur]); } for(int i = 0;i < v.size();i ++){ cout<<v[i]; if(i != v.size()-1) cout<<" "; } cout<<endl; } int main() { cin>>n; for(int i = 0;i < n;i ++) cin>>post_order[i]; for(int i = 0;i < n;i ++) cin>>in_order[i]; bfs(); return 0; }
L2-011 玩轉二叉樹
鏈接: https://pintia.cn/problem-sets/994805046380707840/problems/994805065406070784
思路; 之前比賽沒寫來,寫完上面兩道題后就秒a了。。。
跟前一道基本一樣,就是后序換成了前序,這個知道了原理就很好處理了就是根的在第一個罷了。后面鏡像操作,我們存左右兒子的時候直接交換存就好了。
實現代碼;
#include<bits/stdc++.h> using namespace std; const int M = 1e3 + 10; int pre[M],mid[M],lch[M],rch[M],n; int build(int l1,int r1,int l2,int r2){ if(l1 > r1) return 0; int rt = pre[l2]; int p = l1; while(mid[p] != rt) p++; int cnt = p-l1; rch[rt] = build(l1,p-1,l2+1,l2+cnt); lch[rt] = build(p+1,r1,l2+cnt+1,r2); return rt; } void bfs( ){ vector<int>v; queue<int>q; q.push(build(0,n-1,0,n-1)); while(!q.empty()){ int cur = q.front(); q.pop(); if(lch[cur]) q.push(lch[cur]); if(rch[cur]) q.push(rch[cur]); v.push_back(cur); } for(int i = 0;i < v.size();i ++){ cout<<v[i]; if(i != v.size()-1) cout<<" "; } cout<<endl; } int main() { cin>>n; for(int i = 0;i < n;i ++){ cin>>mid[i]; } for(int i = 0;i < n;i ++){ cin>>pre[i]; } bfs(); return 0; }
