相信大家都知道树有三种遍历,前序遍历,中序遍历,后续遍历。我们平时会遇到一直其中两种遍历结果,让我们求第三种遍历。但并不是每种情况都可能的,有一个特殊情况就是已知前序遍历和后续遍历,我们并不能求出中序遍历,但我们可以求出中序遍历可能出现的情况。
已知前序遍历和中序遍历,求后序遍历
https://www.luogu.com.cn/problem/P1827 模板题链接
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
using ll = long long;
string a, b, c;//a为前序,b为中序,c为后序
//根据前序的顺序为根左右,我们可以知道,前序的首位一定是它的根
//继而我们可以通过find函数,找到该根再中序的位置,找到后,左边就是左子树,右边就是右子树,然后dfs
void solve(string a, string b) {
if (a.empty())return;
char root = a[0];
int k = b.find(root);
a.erase(a.begin());
solve(a.substr(0, k), b.substr(0, k));
solve(a.substr(k), b.substr(k + 1));//左闭右开,对与substr如果只有一个参数,那就一直截到尾
c += root;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
cin >> b >> a;
solve(a, b);
cout << c;
return 0;
}
已知中序遍历和后序遍历,求前序遍历
https://www.luogu.com.cn/problem/P1030 模板题链接
代码具体实现与上面的很相似,可以先试着自己写一遍
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
using ll = long long;
string a, b, c;
void solve(string b, string c) {
if (b.empty())return;//其实判断c也可以,没区别,始终一样长
char root = c[c.size() - 1];//注意这里的处理
int k = b.find(root);
c.erase(c.size() - 1);
a += root;//因为求的是前序,注意顺序
solve(b.substr(0, k), c.substr(0, k));
solve(b.substr(k + 1), c.substr(k));
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
cin >> b >> c;
solve(b, c);
cout << a;
return 0;
}
已知前序遍历和后续遍历,求中序遍历有几种情况
只知道前序遍历和后续遍历是无法求出中序遍历,只能求出中序遍历有几种情况。具体求法见代码。
https://www.luogu.com.cn/problem/P1229 题目链接
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
using ll = long long;
string a, c; ll ans;
//解出这道题的关键在与找到规律
//前序是根左右,后序是左右根,不难发现,左子树和右子树肯定是同时出现的
//但如果前序中出现AB而后序中出现BA明显调换了顺序,
//先序遍历中A如果只有一个子树,A一定在B前面,后序遍历中B一定在A前,很容易想明白。
//如果只有一颗子树是左还是右呢?,就会使结果*2
// AB 前序
// BA 后序
//会出现上图情况
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
cin >> a >> c;
for (int i = 0; i < a.size(); i++) {
for (int j = 1; j < c.size(); j++) {
if (a[i] == c[j] && a[i + 1] == c[j - 1])
ans++;
}
}
cout << (1 << ans);
return 0;
}