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

Posted MangataTS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了L2-004 这是二叉搜索树吗?(二叉树)相关的知识,希望对你有一定的参考价值。

题目连接

https://pintia.cn/problem-sets/994805046380707840/problems/994805070971912192

思路

这道题我们要从二叉搜索树的特性出发,其实也就是题目中提到的:

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

又因为这颗二叉树可能镜像翻转,于是我们需要判断镜像和非镜像是否为二叉搜索树,也就是至多两次判断,其实两次都是几乎一样的,因为左子树的所有节点的最大值是小于右子树所有节点的最小值,那么我们从左子树的左边往右找到第一个大于等于根节点a[root] 的位置l,从右子树的最右边从右往左找到第一个小于根节点a[root] 的位置 r ,那么如果是一个合法的二叉搜索树一定是满足l-r=1(除非节点数为1),那么我们如果是合法的就继续左右子树递归判断其是否合法,最后再将答案放入我们存储的数组或者容器中即可,递归完成后我们只需要判断容器中的长度是否为n 即可,镜像的处理也很简单,请参考代码

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 1000000007
#define endl "\\n"
#define PII pair<int,int>
#define INF 0x3f3f3f3f

const int N = 1e5+10;
int a[N],n;

vector<int> ans;

void dfs1(int root,int tail)
	if(root > tail) return;
	int l = root + 1,r = tail;
	while(a[l] < a[root] && l <= tail) l++;
	while(a[r] >= a[root] && r > root) r--;
	if(l - r != 1) return;//因为要刚好越过分界线
	dfs1(root+1,r);//向左子树递归
	dfs1(l,tail);//向右子树递归
	ans.push_back(a[root]);//将当前的父节点放入答案
	//如果我们发现是一个二叉搜索树那么ans存的就是后根遍历的结果,
	//因为是递归左右子树后才放入ans中的,下面同理


void dfs2(int root,int tail)
	if(root > tail) return;
	int l = root + 1,r = tail;
	while(a[l] >= a[root] && l <= tail) l++;
	while(a[r] < a[root] && r > root) r--;
	if(l - r != 1) return;
	dfs2(root+1,r);
	dfs2(l,tail);
	ans.push_back(a[root]);


int main()

	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin>>n;
	for(int i = 0;i < n; ++i) cin>>a[i];
	
	dfs1(0,n-1);
	if(ans.size() != n)
		ans.clear();
		dfs2(0,n-1);
	
	if(ans.size() == n) 
		cout<<"YES"<<endl;
		for(int i = 0;i < n; ++i) 
			cout<<ans[i]<<" \\n"[i == n-1];
	 else 
		cout<<"NO"<<endl;
	

	return 0;

以上是关于L2-004 这是二叉搜索树吗?(二叉树)的主要内容,如果未能解决你的问题,请参考以下文章

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

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

L2-004 这是二叉搜索树吗? (25 分) (树)

PTA L2-004 这是二叉搜索树吗?-判断是否是对一棵二叉搜索树或其镜像进行前序遍历的结果 团体程序设计天梯赛-练习集

二叉搜索树_BST

二叉搜索树_BST