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

ops/2024/10/21 17:22:16/

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

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

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

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

输入格式:

输入的第一行给出正整数 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

解析:正常的二叉搜索树是左儿子都小于父节点,右儿子全都大于等于父节点,所谓镜像,就是反一下,是左儿子都大于等于父节点,右儿子全都小于父节点,因此我们可以分两个DFS来判断,每次取出左右儿子的所在段落分别递归即可,最后判断存的节点个数是否为N个,如果两个DFS都小于N个,那么就是不合法。

如图:|_u_|__L__|___R__|,合法的子树均满足这样的情况,两段性。

#include <bits/stdc++.h>
using namespace std;
const int N=1e3+5;
int n,a[N];
vector<int> x,y;//分别存正常和镜像的后序遍历节点
void dfs1(int l,int r)//小-大
{if(l>r) return;int tl=-1,tr=-1,root=a[l];for(int i=l+1;i<=r;i++){if(a[i]<root) tl=i;else break;}for(int i=r;i>=l+1;i--){if(a[i]>=root) tr=i;else break;}//因此[l+1,tl]均小于root,[tr,r]均大于等于rootif(tl!=-1) dfs1(l+1,tl);if(tr!=-1) dfs1(tr,r);x.push_back(root);
}
void dfs2(int l,int r)//大-小
{if(l>r) return;int tl=-1,tr=-1,root=a[l];for(int i=l+1;i<=r;i++){if(a[i]>=root) tl=i;else break;}for(int i=r;i>=l+1;i--){if(a[i]<root) tr=i;else break;}if(tl!=-1) dfs2(l+1,tl);if(tr!=-1) dfs2(tr,r);y.push_back(root);
}
void solve()
{scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&a[i]);dfs1(1,n),dfs2(1,n);if(x.size()==n){printf("YES\n");for(int i=0;i<x.size();i++){if(i!=0) printf(" ");printf("%d",x[i]);}printf("\n");return;}if(y.size()==n){printf("YES\n");for(int i=0;i<y.size();i++){if(i!=0) printf(" ");printf("%d",y[i]);}printf("\n");return;}printf("NO\n");
}
int main()
{// freopen("input.txt","r",stdin);// freopen("output.txt","w",stdout);int t=1;//scanf("%d",&t);while(t--) solve();return 0;
}

http://www.ppmy.cn/ops/5571.html

相关文章

如何在 Ubuntu 上启用 IPv6

一、前提条件 一台安装了 Ubuntu 22.04 的计算机具有 sudo 权限的用户账户已连接到支持 IPv6 的网络 二、检查系统是否支持 IPv6 在启用 IPv6 之前&#xff0c;首先要确保您的系统支持 IPv6。要检查内核是否启用了 IPv6&#xff0c;可以运行以下命令&#xff1a; cat /proc/…

笔记wife_assistant

一、wifi_spi_init //------------------------------------------------------------------------------------------------------------------- // 函数简介 WiFi 模块初始化 // 参数说明 *wifi_ssid 目标连接的 WiFi 的名称 字符串形式 // 参数说明 *pass…

设计模式学习笔记 - 开源实战三(中):剖析Google Guava中用到的设计模式

概述 上篇文章&#xff0c;我通过 Google Guava 这样一个优秀的开源类库&#xff0c;讲解了如何在业务开发中&#xff0c;发现跟业务无关、可以复用的通用功能模块&#xff0c;并将它们抽离出来&#xff0c;设计成独立的类库、框架或功能组件。 本章再来学习下&#xff0c;Go…

go 语言 mage 安装踩坑

具体安装代码&#xff1a;mage 官方地址&#xff1a;Mage :: Mage git clone https://github.com/magefile/mage cd mage go run bootstrap.go 在go部署完后&#xff0c;执行上面的脚本&#xff0c;发现最后一句老是执行不成功&#xff1a; rootBDGF-7FPQW93:/home/gw00241401…

OpenHarmony多媒体-mp3agic

简介 mp3agic 用于读取 mp3 文件和读取/操作 ID3 标签&#xff08;ID3v1 和 ID3v2.2 到 ID3v2.4&#xff09;,协助开发者处理繁琐的文件操作相关&#xff0c;多用于操作文件场景的业务应用。 效果展示&#xff1a; 下载安装 ohpm install ohos/mp3agicOpenHarmony ohpm环境配…

机器学习笔记——浅析L2,1范数正则化的线性回归

前言 嘻嘻&#xff0c;刚开始搓逾期了快两周的线性回归实验报告&#xff0c;为了让报告稍微不那么平淡不得不啃论文。 本文从最基本的线性回归开始&#xff0c;对比不同正则化方法的特点和作用&#xff0c;推广到多任务问题并引出L2,1范数正则化&#xff0c;卑微小采购尝试去…

一篇文章带您学会CSS的动画

动画和过渡的区别 过渡&#xff1a;实现两个状态间的变化过程。 动画&#xff1a;实现多个状态间的变化过程。动画过程可控&#xff08;重复播放&#xff0c;最终动画&#xff0c;是否暂停&#xff09; 动画的实现步骤 1.定义动画 书写格式 keyframes 动画名称{from{}to{…

记一次nacos注册服务IP错误的解决方案

我们以常见的微服务脚手架RuoYi-Cloud-Plus 为例 场景 服务网关-》业务服务不通 在微服务场景中&#xff0c;网关会从注册中心获取服务的列表&#xff0c;这些数据以键值对的形式存储在本地缓存中&#xff0c;key是服务的名称&#xff0c;value是服务的IP地址和端口号&#…