L2-004. 这是二叉搜索树吗?

时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
陈越

一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点,

  • 其左子树中所有结点的键值小于该结点的键值;
  • 其右子树中所有结点的键值大于等于该结点的键值;
  • 其左右子树都是二叉搜索树。

所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树。

给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果。

输入格式:

输入的第一行给出正整数N(<=1000)。随后一行给出N个整数键值,其间以空格分隔。

输出格式:

如果输入序列是对一棵二叉搜索树或其镜像进行前序遍历的结果,则首先在一行中输出“YES”,然后在下一行输出该树后序遍历的结果。数字间有1个空格,一行的首尾不得有多余空格。若答案是否,则输出“NO”。

输入样例1:

7
8 6 5 7 10 8 11

输出样例1:

YES
5 7 6 8 11 10 8

输入样例2:

7
8 10 11 8 6 7 5

输出样例2:

YES
11 8 10 7 5 6 8

输入样例3:

7
8 6 8 5 10 9 11

输出样例3:

NO

思路:搜索二叉树的重建,告诉你了前序遍历,那么可以进行递归的找出后序遍历。前序遍历的特性可知,每次递归的查找区间[l,r]的根以及其左右子树,节点l处的值一定是根,因为前序遍历总是先确定出根,之后再去搜索其左子树和右子树。
那么左子树和右子树的范围应当如何确定呢?首先左右子树当中所有的元素的编号应当在[l+1,r]中,并且由搜索树的性质,在根的左子树上的值都小于根,右子树上的值大于等于根,那么容易确定出左右子树了。
之后模拟后续遍历:即先递归搜素左右子树,之后再输出当前节点处的值。
AC代码:
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
#define INF 0x3f3f3f3f
#define EPS 1e-5
#define pi cos(-1)
const int N_MAX = + ;
int n,pos;
bool is_mirror;
vector<int>pre,post;
void dfs(const int& l, const int& r) {//找出[l,r]区间范围的根以及其左右子树
if (l > r)return;
int root = pre[pos++];
int i = l + , j = r;
if (!is_mirror) {//不是镜像,左子树上的值要比root小,右子树上的值大于等于root
while (i <= r&&root>pre[i])i++;
while (j>l&&root <= pre[j])j--;
}
else {
while (i <= r&&root <= pre[i])i++;
while (j >l&&root> pre[j])j--;
}
if (i - j != )return;//如果不是搜索树不满足条件 dfs(l + , j);
dfs(i, r); post.push_back(root);
} int main() {
scanf("%d", &n);
pre.resize(n);
for (int i = ; i < n;i++) {
scanf("%d",&pre[i]);
}
pos = ;
is_mirror = ;
dfs(, n-);
if (post.size()!=n) {
pos = ;
post.clear();
is_mirror = ;
dfs(, n-);
}
if (post.size() == n) {
puts("YES");
for (int i = ; i <n;i++) {
cout << post[i];
if (i + == n)cout << endl;
else cout << " ";
} }
else {
puts("NO");
}
pre.clear(); return ;
}

如果知道后序遍历,让你判断是否是搜索树,如果是,输出前序遍历,方法也类似,贴一下代码:

#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>
#include<string>
#include<iomanip>
#include<map>
#include<stack>
#include<set>
#include<queue>
#include<sstream>
using namespace std;
#define N_MAX 100000+2
#define INF 0x3f3f3f3f
struct Node {
int key=INF, left, right;
Node() {}
Node(int key,int left,int right):key(key),left(left),right(right) {}
}node[N_MAX];
int n,cnt=n-;
vector<int>pre,post;
bool ok = ;
void dfs(int n, int l, int r, bool is_mirror) {
if (l > r)return;
int root = post[cnt--];
int i = l, j = r-;
if (!is_mirror) {
while (i < r&&post[i] <root) i++;
while (j >= l&&post[j] >= root)j--;
}
else {
while (i < r&&post[i] >= root) i++;
while (j >= l&&post[j] < root)j--;
}
if (i - j != ) {
ok = ; return;
}
node[n] = Node(root, * n + , * n + );
dfs(*n+,i, r-,is_mirror);
dfs(*n+,l, j,is_mirror);//!!!
} void preorder(int n) {
pre.push_back(node[n].key);
if (node[*n+].key != INF)preorder(node[n].left);
if (node[*n+].key != INF)preorder(node[n].right);
} int main() {
while (cin >> n) {
post.resize(n);
for (int i = ; i < n; i++)cin >> post[i];
ok = ; cnt = n-;
dfs(,, n - , );
if (!ok) {
ok = ; cnt = n-;
dfs(,, n - , );
if (!ok) {
puts("NO");
}
}
if (ok) {
preorder();
puts("YES");
for (int i = ; i < pre.size(); i++)
printf("%d%c", pre[i], i + == pre.size() ? '\n' : ' ');
}
}
return ;
}

pat 团体天梯赛 L2-004. 这是二叉搜索树吗?的更多相关文章

  1. PAT天梯赛练习题 L3-010. 是否完全二叉搜索树(完全二叉树的判断)

    L3-010. 是否完全二叉搜索树 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 将一系列给定数字顺序插入一个初始为空的二叉搜 ...

  2. 天梯赛练习 L3-010 是否完全二叉搜索树 (30分) 数组建树模拟

    题目分析: 本题的要求是将n个数依次插入一个空的二叉搜索树(左大右小,且没有重复数字),最后需要输出其层次遍历以及判断是否是完全二叉搜索树,通过观察我们发现, 如果这个树是用数组建立的,那么最后输出的 ...

  3. pat 团体天梯赛 L3-007. 天梯地图

    L3-007. 天梯地图 时间限制 300 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 本题要求你实现一个天梯赛专属在线地图,队员输入自己学校 ...

  4. pat 团体天梯赛 L3-015. 球队“食物链”

    L3-015. 球队“食物链” 时间限制 1000 ms 内存限制 262144 kB 代码长度限制 8000 B 判题程序 Standard 作者 李文新(北京大学) 某国的足球联赛中有N支参赛球队 ...

  5. pat 团体天梯赛 L1-039. 古风排版

    L1-039. 古风排版 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 中国的古人写文字,是从右向左竖向排版的.本题就请你编写 ...

  6. pat 团体天梯赛 L2-012. 关于堆的判断

    L2-012. 关于堆的判断 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 将一系列给定数字顺序插入一个初始为空的小顶堆H[] ...

  7. pat 团体天梯赛 L3-010. 是否完全二叉搜索树

    L3-010. 是否完全二叉搜索树 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 将一系列给定数字顺序插入一个初始为空的二叉搜 ...

  8. pat 团体天梯赛 L3-009. 长城

    L3-009. 长城 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 邓俊辉(清华大学) 正如我们所知,中国古代长城的建造是为了抵御外 ...

  9. pat 团体天梯赛 L2-011. 玩转二叉树

    L2-011. 玩转二叉树 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜 ...

  10. pat 团体天梯赛 L2-010. 排座位

    L2-010. 排座位 时间限制 150 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 布置宴席最微妙的事情,就是给前来参宴的各位宾客安排座位. ...

随机推荐

  1. 51nod——1285 山峰和分段(暴力出奇迹)

    要求每段的点数都一样,因此分的段数cnt肯定是n的因子,要求每段都有山峰,因此cnt肯定小于等于山峰数量.分段的宽度d=n/cnt,对山峰数量做一个前缀和,检查一下每一段的山峰数量是否没有增加即可. ...

  2. 14.3-ELK重难点总结和整体优化配置

    本文收录在Linux运维企业架构实战系列 做了几周的测试,踩了无数的坑,总结一下,全是干货,给大家分享~ 一.elk 实用知识点总结 1.编码转换问题(主要就是中文乱码) (1)input 中的cod ...

  3. 一、Linux 安装

    Linux 安装 本章节我们将为大家介绍Linux的安装. 本章节以 centos6.4 为例. centos 下载地址: 可以去官网下载最新版本:https://www.centos.org/dow ...

  4. Vue2+webpack+node 配置+入门+详解

    Vue2介绍 1.vue2.0 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架. Vue 的核心库只关注视图层 采用单文件组件 复杂大型单页应用程序(SPA) 响 ...

  5. JZOJ 3388. 【NOIP2013模拟】绿豆蛙的归宿

    3388. [NOIP2013模拟]绿豆蛙的归宿 (Standard IO) Time Limits: 1000 ms  Memory Limits: 131072 KB  Detailed Limi ...

  6. Python中的dict

    dict_lst = [ ('字典的键必须可哈希',), ('字典的键重复覆盖',), ('字典可迭代') ('增',), ('删',), ('改',), ('查',), ('练习',), ] 字典的 ...

  7. 常州大学新生寒假训练会试 I 合成反应

    题目描述 有机合成是指从较简单的化合物或单质经化学反应合成有机物的过程. 有时也包括从复杂原料降解为较简单化合物的过程. 由于有机化合物的各种特点,尤其是碳与碳之间以共价键相连,有机合成比较困难,常常 ...

  8. secureCRT中vim行号下划线问题

    在vim中发现开启显示行号(set number)或语法高亮(syntax on)时,发现文档中很多地方都有下划线,对视觉产生极大干扰.开始还以为是vim的某个配置造成的,后来发现真正的元凶是secu ...

  9. PAT Advanced 1001

    1001 A+B Format (20 分) Calculate a+b and output the sum in standard format -- that is, the digits mu ...

  10. Harbor HA部署-使用Ceph RADOS后端

    1. 前言 Harbor 1.4.0版本开始提供了HA部署方式,和非HA的主要区别就是把有状态的服务分离出来,使用外部集群,而不是运行在本地的容器上.而无状态的服务则可以部署在多个节点上,通过配置上层 ...