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. JavaScript设置div中的文字滚动起来 实现滚动效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. JS - Array.slice 与 Array.splice

    1)Array.slice方法   1.1)接收两个参数:              a:起始下标              b:结束下标   1.2)返回由a(包括)至b(不包括)的元素所组成的数组 ...

  3. python 使用requests 请求 https 接口 ,取消警告waring

    response = requests.request("POST", url, timeout=20, data=payload, headers=headers, proxie ...

  4. selenium 双击元素

    #定位元素 pod_input = driver.find_element(By.ID, 'j_idt9:searchForm:j_idt11:toSelectorLocation:toSelecto ...

  5. spring boot 集成swagger2

    1  在pom.xml中加入Swagger2的依赖 <dependency> <groupId>io.springfox</groupId> <artifac ...

  6. js控制台输出图案

    控制台输出图案 console.log([ " _ooOoo_", " o8888888o", " 88\" . \"88&quo ...

  7. php实现的三个常用加密解密功能函数示例

    目录 算法一: 算法二: 算法三(改进第一个加密之后的算法) 本文实例讲述了php实现的三个常用加密解密功能函数.分享给大家供大家参考,具体如下: 算法一: //加密函数 function lock_ ...

  8. LightOJ 1141 Number Transformation

    Number Transformation In this problem, you are given an integer number s. You can transform any inte ...

  9. Diycode开源项目 Glide图片加载分析

    1.使用Glide前的准备 1.1.首先要build.gradle中添加   github原地址点击我. 参考博客:Glide-开始! 参考博客:android图片加载库Glide的使用介绍. 参考博 ...

  10. Android stadio

    Android stadio 最近遇到大问题,就是主功能行.但是让它做库工程,他就不管用. 但是在eclipse里面就可以.