题目链接:传送门
思路:这个题是通过二叉树的先序遍历和后序遍历推中序,但是先序和后序是无法唯一确定一颗二叉树的,为什么呢?首先设两个序列为pre[n] , 和 post[n] , 先序的第一个节点pre[0]和后序最后一个节post[ n - 1 ]点是头结点,如果头结点有两棵子树,那么结构是确定的,比如后序的倒数第二个节点p[n - 2]是头结点的右子树,在先序中找到这个节点的位置pre[ l ] , 那pre[2]到pre[l - 1]是头结点的左子树。但是如果 l = 2 ,即头结点只有一颗子树 那么我们不确定pre[2] — pre[n - 1]是头结点的左子树还是头结点的右子树,但是应为只有一颗子树,不论把它当左子树还是右子树,都不会影响子树的结构,所以遇到这种情况可以全当成右子树的来处理.
对于本题,只需判断是否有一个子树的情况即可,如果有的话就有两种以上二叉树,输出"No",否则输出"Yes"。
然后直接存储当前遍历到的头结点即可。(具体请看代码)
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100;
int pre[maxn] , post[maxn];
int n;
vector <int> ans;
bool flag;
void dfs(int pl , int pr , int pol , int por) {
if(pl == pr) {
ans.push_back(pre[pl]);
return;
}
int i = 0;
while(i + pl + 1 <= pr && pre[i + pl + 1] != post[por - 1])i++;
if(i > 0) {
dfs( pl + 1 , pl + i , pol , pol + i - 1);
}
else flag = 1;
ans.push_back(pre[pl]);
dfs(pl + i + 1 , pr , pol + i , por - 1);
}
int main() {
ios::sync_with_stdio(0);
cin >> n;
for(int i = 0 ; i < n ; i++) {
cin >> pre[i];
}
for(int i = 0 ; i < n ; i++) {
cin >> post[i];
}
flag = 0;
dfs(0 , n - 1, 0 , n - 1);
if(!flag) cout << "Yes\n";
else cout << "No\n";
for(int i = 0 ; i < ans.size() ; i++) {
if(i > 0)cout << " ";
cout << ans[i];
}
cout << "\n";
return 0;
}