pat 团体天梯赛 L2-004. 这是二叉搜索树吗?
L2-004. 这是二叉搜索树吗?
一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点,
- 其左子树中所有结点的键值小于该结点的键值;
- 其右子树中所有结点的键值大于等于该结点的键值;
- 其左右子树都是二叉搜索树。
所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树。
给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果。
输入格式:
输入的第一行给出正整数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. 这是二叉搜索树吗?的更多相关文章
- PAT天梯赛练习题 L3-010. 是否完全二叉搜索树(完全二叉树的判断)
L3-010. 是否完全二叉搜索树 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 将一系列给定数字顺序插入一个初始为空的二叉搜 ...
- 天梯赛练习 L3-010 是否完全二叉搜索树 (30分) 数组建树模拟
题目分析: 本题的要求是将n个数依次插入一个空的二叉搜索树(左大右小,且没有重复数字),最后需要输出其层次遍历以及判断是否是完全二叉搜索树,通过观察我们发现, 如果这个树是用数组建立的,那么最后输出的 ...
- pat 团体天梯赛 L3-007. 天梯地图
L3-007. 天梯地图 时间限制 300 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 本题要求你实现一个天梯赛专属在线地图,队员输入自己学校 ...
- pat 团体天梯赛 L3-015. 球队“食物链”
L3-015. 球队“食物链” 时间限制 1000 ms 内存限制 262144 kB 代码长度限制 8000 B 判题程序 Standard 作者 李文新(北京大学) 某国的足球联赛中有N支参赛球队 ...
- pat 团体天梯赛 L1-039. 古风排版
L1-039. 古风排版 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 中国的古人写文字,是从右向左竖向排版的.本题就请你编写 ...
- pat 团体天梯赛 L2-012. 关于堆的判断
L2-012. 关于堆的判断 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 将一系列给定数字顺序插入一个初始为空的小顶堆H[] ...
- pat 团体天梯赛 L3-010. 是否完全二叉搜索树
L3-010. 是否完全二叉搜索树 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 将一系列给定数字顺序插入一个初始为空的二叉搜 ...
- pat 团体天梯赛 L3-009. 长城
L3-009. 长城 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 邓俊辉(清华大学) 正如我们所知,中国古代长城的建造是为了抵御外 ...
- pat 团体天梯赛 L2-011. 玩转二叉树
L2-011. 玩转二叉树 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜 ...
- pat 团体天梯赛 L2-010. 排座位
L2-010. 排座位 时间限制 150 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 布置宴席最微妙的事情,就是给前来参宴的各位宾客安排座位. ...
随机推荐
- JavaScript设置div中的文字滚动起来 实现滚动效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- JS - Array.slice 与 Array.splice
1)Array.slice方法 1.1)接收两个参数: a:起始下标 b:结束下标 1.2)返回由a(包括)至b(不包括)的元素所组成的数组 ...
- python 使用requests 请求 https 接口 ,取消警告waring
response = requests.request("POST", url, timeout=20, data=payload, headers=headers, proxie ...
- selenium 双击元素
#定位元素 pod_input = driver.find_element(By.ID, 'j_idt9:searchForm:j_idt11:toSelectorLocation:toSelecto ...
- spring boot 集成swagger2
1 在pom.xml中加入Swagger2的依赖 <dependency> <groupId>io.springfox</groupId> <artifac ...
- js控制台输出图案
控制台输出图案 console.log([ " _ooOoo_", " o8888888o", " 88\" . \"88&quo ...
- php实现的三个常用加密解密功能函数示例
目录 算法一: 算法二: 算法三(改进第一个加密之后的算法) 本文实例讲述了php实现的三个常用加密解密功能函数.分享给大家供大家参考,具体如下: 算法一: //加密函数 function lock_ ...
- LightOJ 1141 Number Transformation
Number Transformation In this problem, you are given an integer number s. You can transform any inte ...
- Diycode开源项目 Glide图片加载分析
1.使用Glide前的准备 1.1.首先要build.gradle中添加 github原地址点击我. 参考博客:Glide-开始! 参考博客:android图片加载库Glide的使用介绍. 参考博 ...
- Android stadio
Android stadio 最近遇到大问题,就是主功能行.但是让它做库工程,他就不管用. 但是在eclipse里面就可以.