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. LeetCode955删列造序 ||

    问题:删列造序 || 给定由 N 个小写字母字符串组成的数组 A,其中每个字符串长度相等. 选取一个删除索引序列,对于 A 中的每个字符串,删除对应每个索引处的字符. 比如,有 A = [" ...

  2. day23-python之日志 re模块

    1.logging import logging #-----------------------------------logging.basicConfig logging.basicConfig ...

  3. (转)curl常用命令

    本文转自 http://www.cnblogs.com/gbyukg/p/3326825.html 下载单个文件,默认将输出打印到标准输出中(STDOUT)中 curl http://www.cent ...

  4. 2017 ACM-ICPC EC-Final ShangHai(思维乱搞赛)

    感觉全是思维乱搞题. Gym - 101775J Straight Master 给你n种扑克,你每次可以出连续的3 ~ 5 张,问你能否出完. Sample Input 2 13 1 2 2 1 0 ...

  5. linux系统下单节点hadoop2的配置

    Jdk安装: jdk-7u45-linux-x64.gz cp jdk-7u45-linux-x64.gz /usr/java/ cd /usr/java/ tar -zxvf jdk-7u45-li ...

  6. datagrid的基本属性&查询和清空功能的实现

    1.datagrid基本属性 <script charset=UTF-8"> $(function(){ $("#datagrid").datagrid({ ...

  7. [转载]robotium脚本封装为APK,实现脱离手机数据线,使用按钮点击控制用例

    原文地址:robotium脚本封装为APK,实现脱离手机数据线,使用按钮点击控制用例运行作者:机器,猫 最近一直在完成一些robotium的小功能,用来更方便的完成一些小功能的测试,或者可以说用来娱乐 ...

  8. maven文件报错(pom.xml或者jar包缺失)解决方法

    相信很多朋友在myeclipse上把maven配置好了,但是新建maven项目的时候会报错,下面我来总结以下我遇到的问题. 新建完maven项目后,pom.xml报错 1.报错的原因:很多时候我们在下 ...

  9. hnust Snowman

    问题 D: Snowman 时间限制: 1 Sec  内存限制: 128 MB提交: 203  解决: 94[提交][状态][讨论版] 题目描述 前言:这是某比赛的热身题,本题主要考察英文水平,只要看 ...

  10. 双网卡只有一个能ping通的解决办法

    来源:http://blog.csdn.net/centerpoint/article/details/38542719 Linux默认启用了反向路由检查 如果2个网卡在一个Lan里面,那么服务器可能 ...