题目链接:P1827 [USACO3.4] 美国血统 American Heritage - 洛谷 | 计算机科学教育新生态
题目难度:普及
首先介绍下二叉树的遍历:
学过数据结构都知道二叉树有三种遍历:
1.前序遍历:根左右
2.中序遍历:左根右
3.后序遍历:左右根
解题思路: 前序遍历是先遍历根节点,再遍历根节点的左右子树。那么,前序序列的第一个节点,一定是根 节点。找到根节点,再确定根节点在中序序列中的位置,就可以分出左右两棵子树。这道题就可以不用建树直接递归来求就好了
下面奉上代码部分:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
string front, middle;
void dfs(string front, string middle)
{
// 如果前序遍历为空,说明没有节点,直接返回
if (front.size() < 1) return;
// 找到当前根节点在中序遍历中的位置
int t = middle.find(front[0]);
// 递归处理左子树:前序遍历从1开始,长度是t;中序遍历是前t个字符
dfs(front.substr(1, t), middle.substr(0, t));
// 递归处理右子树:前序遍历从t+1开始,长度是front.size() - t - 1;中序遍历是从t+1到结尾
dfs(front.substr(t + 1, front.size() - t - 1), middle.substr(t + 1, front.size() - t - 1));
// 输出当前节点(先序遍历的根节点)
cout << front[0];
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> middle >> front;//注意题目要求先输入中序然后是前序
dfs(front, middle);
return 0;
}