PAT甲级1138Postorder Traversal
题目链接
https://pintia.cn/problem-sets/994805342720868352/problems/994805345078067200
题解
题目要求
假设二叉树中所有结点的值都是互异的正整数,给定二叉树的先序和后序遍历,请输出该树后序遍历的第一个数字。
- 输入
- N:正整数,不超过50000,二叉树中结点的数量
- 先序遍历结果
- 中序遍历结果
解题思路
-
根据先序遍历和中序遍历结果可以确定一颗树,这道题的关键就是如何确定出这颗树并遍历它。
可以参考PAT甲级1151LCA in a Binary Tree,这道题里也是根据先序遍历和中序遍历结果确定出了一棵树。
-
设置全局flag判断是否是该树后序遍历的第一个数字,如果是则输出,不是则不输出
代码
// Problem: PAT Advanced 1138
// URL: https://pintia.cn/problem-sets/994805342720868352/problems/994805345078067200
// Tags: Tree DFS
#include <iostream>
#include <vector>
#include <map>
using namespace std;
vector<int> preOrder; // 先序遍历结果
vector<int> inOrder; // 中序遍历结果
map<int, int> inPos; // 结点到中序遍历结果inOrder索引的映射
bool firstIsPrinted = false; // 为true代表后序遍历时的第一个结点已经输出
void postOrderTraverse(int inLeft, int inRight, int preRoot){
if (firstIsPrinted) // 只输出后序遍历的第一个结点即可
return ;
if (inRight < inLeft) // 该树不存在
return ;
int inRoot = inPos[preOrder[preRoot]]; // 当前树的根结点在中序遍历结果inOrder中的索引
// 后序遍历
postOrderTraverse(inLeft, inRoot - 1, preRoot + 1); // 遍历左子树并判断左子树是否存在
postOrderTraverse(inRoot + 1, inRight, preRoot + 1 + (inRoot - inLeft)); // 遍历右子树并判断右子树是否存在
if (!firstIsPrinted){ // 只输出后序遍历的第一个结点即可
printf("%d", inOrder[inRoot]);
firstIsPrinted = true;
}
}
int main()
{
int n;
scanf("%d", &n);
preOrder.resize(n + 1);
inOrder.resize(n + 1);
for (int i = 1; i <= n; i++) // 读取先序遍历结果
scanf("%d", &preOrder[i]);
for (int i = 1; i <= n; i++){ // 读取中序遍历结果
scanf("%d", &inOrder[i]);
inPos[inOrder[i]] = i;
}
postOrderTraverse(1, n, 1);
return 0;
}
作者:@臭咸鱼
转载请注明出处:https://www.cnblogs.com/chouxianyu/
欢迎讨论和交流!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!
· 用 C# 插值字符串处理器写一个 sscanf