PAT-A1119 題解
PAT-A 1119 題解
題意分析
這道題要求我們通過後序遍歷和先序遍歷的順序還原一顆二叉樹,同時把它的中序遍歷順序列印出來。
當然還必須判斷,這樣的二叉樹是否是唯一的。
演算法分析
本題的核心就在於還原出這個二叉樹。首先我們得明白,什麼情況下,我們不能還原出一顆唯一的二叉樹?
答案就是,如果在先序遍歷的序列中發發現,根節點後面的左右兒子結點只有一個,這個時候我們並不知道它到底是左兒子還是右兒子,所以產生了歧義。為了消除這個歧義,我們就直接假設它是左兒子。消除歧義的同時,給這個二叉樹打上標記。
AC程式碼
#include<unordered_map>
#include<iostream>
#include<math.h>
#include<string>
int cnt = 0;
using namespace std;
bool is_unique = true;
unordered_map<int, int> pre_map, post_map;
int n;
const int MAX_N = 32;
struct node
{
node* lc, * rc;
int val;
};
int pre[MAX_N], post[MAX_N];
/*
判斷是否唯一的標準是,當一個結點的子節點只有一個的時候,
我們無法判斷它到底是左兒子還是右兒子。
由於答案要求輸出一種結果即可,所以我們就預設他為左兒子。
*/
node* create_tree(int preL, int preR, int postR) {//postR表示post的根節點下標
if (preL > preR || postR < 1) return NULL;
node* root = new node();
root->val = pre[preL];
if(preL == preR){
root->lc = root->rc = NULL;
return root;
}
if(pre[preL+1] == post[postR-1]){//產生了左右兒子相同的情況
root->lc = create_tree(preL+1,preR,postR-1);
root->rc = NULL;
return root;
}
//右兒子在pre陣列中的位置
int pre_rc_pos = pre_map[post[postR - 1]];
//左兒子在post陣列中的位置
int post_lc_pos = post_map[pre[preL + 1]];
//右子樹的結點個數
root->lc = create_tree(preL + 1, pre_rc_pos - 1, post_lc_pos);
root->rc = create_tree(pre_rc_pos, preR, postR - 1);
return root;
}
node* build(int preL, int preR, int postL, int postR) {
if (preL > preR || postL > postR || preL == 0 || postL == 0) return NULL;
node* root = new node;
root->val = pre[preL];//或者取post[postR]
if (preL == preR) {
root->lc = root->rc = NULL;
return root;
}
//右兒子在pre陣列中的位置
int pre_rc_pos = pre_map[post[postR - 1]];
//左兒子在post陣列中的位置
int post_lc_pos = post_map[pre[preL + 1]];
if (post[postR - 1] == pre[preL + 1]) {//當產生了左右兒子相同的情況
is_unique = false;
root->lc = build(preL + 1, preR, postL, postR - 1);
root->rc = NULL;
return root;
}
root->lc = build(preL + 1, pre_rc_pos - 1, postL, post_lc_pos);
root->rc = build(pre_rc_pos, preR, post_lc_pos + 1, postR - 1);
return root;
}
void inOrder(node* root) {
if (root == NULL) return;
inOrder(root->lc);
cout << root->val; cnt++;
if (cnt != n) {
cout << " ";
}
else cout << endl;
inOrder(root->rc);
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> pre[i];
pre_map[pre[i]] = i;
}
for (int i = 1; i <= n; i++) {
cin >> post[i];
post_map[post[i]] = i;
}
node* root = build(1, n,1, n);
string msg = is_unique ? "Yes" : "No";
cout << msg << endl;
inOrder(root);
system("pause");
return 0;
}
相關文章
- 題解
- 解題
- 每日"兩"題 題解
- XYCTF pwn部分題解 (部分題目詳解)
- 無題號 分配問題 題解
- 火星商店問題 題解
- LeetCode題解第122題LeetCode
- 排列 題解
- 20240805題解
- Determinant 題解NaN
- 20240726題解
- 題解集合
- Minlexes題解
- 杯子題解
- OVO題解
- 樹的解構 題解
- Tarjan縮點題單 刷題題解
- csp-s真題題解
- 【題解】Solution Set - 「藍」題板刷
- 雙模數問題 題解
- 《扶蘇的問題》題解
- leetcode題解(陣列問題)LeetCode陣列
- Leetcode題解1-50題LeetCode
- 費解的開關 - 題解
- CF 1823 題解
- CF 1253 題解
- CF 705 題解
- CF 1339 題解
- Removing People 題解REM
- 彈珠 題解
- 數列 題解
- 聯考題解
- 食物鏈題解
- ρars/ey 題解
- ABC 367 題解
- Cheap Robot 題解
- 題解目錄
- 圖騰 - 題解