(先说一句,题目还不错,很值得动手思考并且去实现。)

题意:根据前序遍历和后序遍历建树,输出中序遍历序列,序列可能不唯一,输出其中一个即可。  

  已知前序遍历和后序遍历序列,是无法确定一棵二叉树的,原因在于如果只有一棵子树可能是左孩子也有可能是右孩子。由于只要输出其中一个方案,所以假定为左孩子即可。下面就是如何根据前序和后序划分出根节点和左右孩子,这里需要定义前序和后序的区间范围,分别为[preL,preR],[postL,postR]。  

  一开始区间都为[1,n],可以发现前序的第一个和后序的最后一个为根节点root,前序的第二个值val为其某子树的根节点(但还无法确定是左孩子or右孩子)。在后序中找对应的值所在的位置postIdx,则postIdx之前的节点均为val的孩子节点,统计其个数num。那么我们就可以划分区间:  

若num个数=preR-preL-1,即val后面的个数都是其子节点,那么二叉树不唯一,将其作为root的左子树处理。

否则划分为左子树区间和右子树对应的前序和后序区间,顺便更新下root的左孩子preL+1,右孩子preL+num+2:
preOrder:[preL+1,preL+num+1],postOrder:[postL,postIdx];
preOrder:[preL+num+2,preR],postOrder:[postIdx+1,postR-1];
然后递归划分即可

拿样例举例:
1 (2) [3 {4 6 7} <5>]
(2) [{6 7 4} <5> 3] 1
不同的括号对应不同的子树区间
第一次递归划分了(2)-(2),[3 4 6 7 5]-[6 7 4 5 3]
由于(2)只有一棵,不继续划分。
第二次递归划分了{4 6 7}-{6 7 4},<5>-<5>
第三次递归划分了(6)-(6),(7)-(7)
结束

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string.h> using namespace std;
const int maxn=;
int preOrder[maxn];
int postOrder[maxn];
bool isUnique=true;
struct Node{
int left=-,right=-;
}node[maxn]; /*
[preL,preR] is current sequence interval of pre-order
[postL,postR] is current sequence interval of post-order
*/
void build(int preL,int preR,int postL,int postR){
if(preL>=preR){
return;
}
int fa=preL;
//前序遍历的第一个为根节点,第二个为子树的根节点,可能是左孩子也可能是右孩子
int val=preOrder[preL+];
int postIdx;
for(int i=postL;i<postR;i++){
if(val==postOrder[i]){
postIdx=i; //val在后序遍历中的索引
break;
}
}
int num=postIdx-postL; //以val为根节点的子树节点个数
//即以val为根节点的子树只有一棵孩子,那么既可以为左孩子也可以为右孩子,所以不唯一
if(preR-preL-==num){
isUnique=false;
}
node[fa].left=preL+; //不唯一的话,看做左孩子
build(preL+,preL+num+,postL,postIdx);
//如果以preL+1为根节点的子树的节点个数小于fa的所有子树节点的个数,说明fa还有右孩子
if(preR-preL->num){
node[fa].right=preL+num+;
build(preL+num+,preR,postIdx+,postR-);
}
} bool first=true;
void inOrder(int root){
if(root==-){
return;
}
inOrder(node[root].left);
if(first){
first=false;
printf("%d",preOrder[root]);
}
else
printf(" %d",preOrder[root]);
inOrder(node[root].right);
}
int main()
{
int n;
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&preOrder[i]);
for(int i=;i<=n;i++)
scanf("%d",&postOrder[i]);
build(,n,,n);
if(isUnique)
printf("Yes\n");
else
printf("No\n");
inOrder();
printf("\n"); //否则格式错误
return ;
}

PAT甲题题解-1119. Pre- and Post-order Traversals (30)-(根据前序、后序求中序)的更多相关文章

  1. PAT甲题题解1099. Build A Binary Search Tree (30)-二叉树遍历

    题目就是给出一棵二叉搜索树,已知根节点为0,并且给出一个序列要插入到这课二叉树中,求这棵二叉树层次遍历后的序列. 用结构体建立节点,val表示该节点存储的值,left指向左孩子,right指向右孩子. ...

  2. PAT甲题题解-1115. Counting Nodes in a BST (30)-(构建二分搜索树+dfs)

    题意:给出一个序列,构建二叉搜索树(BST),输出二叉搜索树最后两层的节点个数n1和n2,以及他们的和sum: n1 + n2 = sum 递归建树,然后再dfs求出最大层数,接着再dfs计算出最后两 ...

  3. PAT甲题题解-1064. Complete Binary Search Tree (30)-中序和层次遍历,水

    由于是满二叉树,用数组既可以表示父节点是i,则左孩子是2*i,右孩子是2*i+1另外根据二分搜索树的性质,中序遍历恰好是从小到大排序因此先中序遍历填充节点对应的值,然后再层次遍历输出即可. 又是一道遍 ...

  4. PAT甲题题解-1030. Travel Plan (30)-最短路+输出路径

    模板题最短路+输出路径如果最短路不唯一,输出cost最小的 #include <iostream> #include <cstdio> #include <algorit ...

  5. PAT甲题题解-1068. Find More Coins (30)-dp,01背包

    一开始没多想,虽然注意到数据N<=10^4的范围,想PAT的应该不会超时吧,就理所当然地用dfs做了,结果最后一组真的超时了.剪枝啥的还是过不了,就意识到肯定不是用dfs做了.直到看到别人说用0 ...

  6. PAT甲题题解-1003. Emergency (25)-最短路径+路径数目

    给出n个城市,m条边,起始点c1和目的点c2接下来给出n个城市的队伍数以及m条双向边问你求c1到c2的所有最短路径数目,以及其中经过的最多队伍数 先最短路dijkstra,同时建立vector数组pr ...

  7. PAT甲题题解-1008. Elevator (20)-大么个大水题,这也太小瞧我们做题者的智商了

    如题... #include <iostream> #include <cstdio> #include <algorithm> #include <cstr ...

  8. PAT甲题题解-1010. Radix (25)-二分搜索

    题意:给出n1和n2,以及其中一个数的进制,问另一个数是多少进制的情况下,才会是两个数相等.不存在的话,则输出Impossible 这题思路很简单,但是要考虑的比较多,在简单题里面算是比较好的. 有两 ...

  9. PAT甲题题解-1011. World Cup Betting (20)-误导人的水题。。。

    题目不严谨啊啊啊啊式子算出来结果是37.975样例输出的是37.98我以为是四舍五入的啊啊啊,所以最后输出的是sum+0.005结果告诉我全部错误啊结果直接保留两位小数就可以了啊啊啊啊 水题也不要这么 ...

随机推荐

  1. hyper-v NAT网络

    宿主机:windows 2008 R2 企业版 hyper-V配置静态IP地址 https://jingyan.baidu.com/article/925f8cb8ae1ee2c0dde05632.h ...

  2. PyQt5--QPixmap

    # -*- coding:utf-8 -*- ''' Created on Sep 20, 2018 @author: SaShuangYiBing Comment: ''' import sys f ...

  3. React阻止事件冒泡的正确打开方式

    需求:点击导航list按钮出现侧弹框,点击空白处弹框消失 问题:绑定空白处的点击事件到document上,但是非空白处的点击也会触发这个点击事件,在react中如何阻止事件冒泡? 解决方法:e.sto ...

  4. react-navigation 使用笔记 持续更新中

    目录 基本使用(此处基本使用仅针对导航头部而言,不包含tabbar等) header怎么和app中通信呢? React-Navigation是目前React-Native官方推荐的导航组件,代替了原用 ...

  5. BZOJ1458:士兵占领(有上下界最小流)

    Description 有一个M * N的棋盘,有的格子是障碍.现在你要选择一些格子来放置一些士兵,一个格子里最多可以放置一个士兵,障碍格里不能放置士兵.我们称这些士兵占领了整个棋盘当满足第i行至少放 ...

  6. P3324 [SDOI2015]星际战争

    传送门:https://www.luogu.org/problemnew/show/P3324 首先瞅一眼数据范围,发现m, n都很小,所以就可以初步断定这是一道网络流的题. 因为题中说每一个武器只能 ...

  7. javascript:void(0)的问题

    最近看了好几个关于<a>标签和javascript:void(0)的帖子,谨记于此,以资查阅. 注:以下代码未经全面测试,但每一种方法可能会出现的情况都基本做了说明. 在做页面时,如果想做 ...

  8. pam_frpintd.so 错误修复

    PAM unable to dlopen(/lib64/security/pam_fprintd.so): /lib64/security/pam_fprintd.so: cannot open sh ...

  9. Linux下RPM包的安装

    Linux下RPM包安装 二进制包(RPM包.系统默认包) RPM安装 rpm -ivh 包全名(查询依赖网址:http://www.rpmfind.net) -i(install):安装 -v(ve ...

  10. WorldWind源码剖析系列:插件类Plugin、插件信息类PluginInfo和插件编译器类PluginCompiler

    插件类Plugin是所有由插件编译器加载的插件子类的抽象父类,提供对插件的轻量级的访问控制功能. 插件信息类PluginInfo用来存储关于某个插件的信息的类,可以理解为对插件类Plugin类的进一步 ...