前言
本章节聚焦算法题实战,通过两道经典题目讲解递归、深搜、宽搜等核心思想。从遍历重建到树形结构属性计算,每道题都在训练分治思维与代码实现能力。
一、美国血统 American Heritage
1. 题目描述
链接: 洛谷 P1827
给定一棵二叉树的中序遍历序列和后序遍历序列,要求输出其先序遍历序列。
2. 算法原理
解法同求先序序列,核心在于利用后序遍历的最后一个元素确定根节点,再在中序遍历中找到该根节点的位置,从而划分左右子树的范围。手动模拟一下流程,找出「相同子问题」,使用递归求解。
步骤:
- 处理左右子树
- 定位根节点
- 划分左右子树区间
3. 代码实现
#include <iostream>
#include <string>
using namespace std;
string a, b; // a:中序遍历,b:后序遍历
void dfs(int l1, int r1, int l2, int r2) {
// 递归窗口:l1,r1 为当前中序区间,l2,r2 为当前后序区间
if (l1 > r1) return;
// 寻找中序遍历中根节点的位置
// 后序遍历的最后一个元素是当前子树的根
int p = l1;
while (a[p] != b[r2]) p++;
// 递归处理左子树
// 左子树中序范围:[l1, p-1]
// 左子树后序范围:[l2, l2 + (p - 1 - l1)]
dfs(l1, p - 1, l2, l2 + p - l1 - 1);
// 递归处理右子树
// 右子树中序范围:[p+1, r1]
// 右子树后序范围:[l2 + (p - 1 - l1) + 1, r2 - 1]
dfs(p + 1, r1, l2 + p - l1, r2 - );
cout << b[r2];
}
{
cin >> a >> b;
(, a.() - , , b.() - );
;
}


