首页 > 编程语言 >验证二叉搜索树的C++实现多种解法

验证二叉搜索树的C++实现多种解法

时间:2023-01-22 10:01:45浏览次数:43  
标签:pre right return C++ 二叉 bool root 解法 isValidBST



tags: C++ DSA BinaryTree

写在前面

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

  • 节点的左子树只包含 小于 当前节点的数。
  • 节点的右子树只包含 大于 当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

提示:

  • 树中节点数目范围在验证二叉搜索树的C++实现多种解法_中序遍历
  • 验证二叉搜索树的C++实现多种解法_数据结构_02.

本质上就是中序遍历的应用, 因为二叉搜索树中序遍历的结果是一个严格的单调增序列.

第一种思路:先存数组, 然后判断

这里我一开始想的是集合去重然后判断排序数组, 但是内存飙升.

class Solution {
public:
bool isValidBST(TreeNode* root) {
if (!root)return true;
vector<int> v{};
function<void(TreeNode*)> f=[&](TreeNode* cur){
if(!cur)return ;
f(cur->left);
v.emplace_back(cur->val);
f(cur->right);
};
f(root);
auto vv(v);
set<int> s(v.begin(),v.end());
sort(v.begin(),v.end());
return s.size()==v.size()&&v==vv;
}
};

那么接下来的一种改进就是直接判断数组了, 如下:

class Solution {
public:
bool isValidBST(TreeNode* root) {
if (!root)return true;
vector<int> v{};
function<void(TreeNode*)> f=[&](TreeNode* cur){
if(!cur)return ;
f(cur->left);
v.emplace_back(cur->val);
f(cur->right);
};
f(root);
for(int i{1};i<v.size();++i)
if (v[i-1]>=v[i]) return false;
return true;
}
};

但是还是不是最优解.

第二种思路: 遍历同时比较

遍历时候进行比较, 用到了中序遍历的递归写法:

class Solution {
public:
long pre=INT64_MIN;
bool isValidBST(TreeNode* root) {
if (!root)return true;
bool left=isValidBST(root->left);
if(root->val>pre)pre=root->val;
else return false;
bool right=isValidBST(root->right);
return left&&right;
}
};

不用最小值也可以:

class Solution {
public:
TreeNode* pre{};
bool isValidBST(TreeNode* root) {
if (!root)return true;
bool left=isValidBST(root->left);
if(pre)if(root->val>pre->val)pre=root;
else return false;
else pre=root;
bool right=isValidBST(root->right);
return left&&right;
}
};

判断部分看起来有点乱, 精简一下:

class Solution {
public:
TreeNode* pre{};
bool isValidBST(TreeNode* root) {
if (!root)return true;
bool left=isValidBST(root->left);
if(pre&&root->val<=pre->val) return false;
pre=root;
bool right=isValidBST(root->right);
return left&&right;
}
};

顺便巩固一下中序遍历迭代写法:

class Solution {
public:
bool isValidBST(TreeNode* root) {
if(!root)return true;
stack<TreeNode*>st;
TreeNode* pre{};
while(!st.empty()||root){
if(root){
st.push(root);
root=root->left;
} else {
root=st.top(); st.pop();
// 操作
if (pre&&pre->val>=root->val)return false;
pre=root;
root=root->right;
}
}
return true;
}
};


标签:pre,right,return,C++,二叉,bool,root,解法,isValidBST
From: https://blog.51cto.com/u_15366127/6021432

相关文章

  • 详细实例说明+典型案例实现 对迭代法进行全面分析 | C++
    第四章迭代法:::hljs-center目录第四章迭代法●前言●一、迭代法是什么?1.简要介绍2.代码示例(简单理解)3.生活实例●二、迭代法的典型案例——开平方&帕......
  • C++的宏利用include和undef来重复使用
    如dll导出函数,需要定义以及QueryInterface,其中函数有多个,如果想代码尽量简洁,只有这个方法定义#defineNVIDIA_API_DEF(_fun) decltype(_fun) *_##_fun=NUL......
  • 算法编程 dfs 从先序和中序遍历还原二叉树
    105.从前序与中序遍历序列构造二叉树给定两个整数数组 preorder和inorder ,其中 preorder是二叉树的先序遍历,inorder 是同一棵树的中序遍历,请构造二叉树并返回......
  • c++中运算符重载总结
    运算符重载的本质是函数重载。语法格式重载函数的一般格式如下:返值类型operator运算符名称(形参表列){    重载实体;}operator运算符名称在一起构成了新的函......
  • [C/C++] 简单实现按字符分割字符串split函数
    记录一下/***字符串str通过字符target进行分割*/vector<string>split(stringstr,chartarget){vector<string>res;intpos=0;while(po......
  • c/c++ mysql api函数
    一、常用APImysql_affected_rows()返回上次UPDATE、DELETE或INSERT查询更改/删除/插入的行数。mysql_autocommit()切换autocommit模式,ON/OFFmysql_change_user()......
  • 代码随想录day23 669. 修剪二叉搜索树 108. 将有序数组转换为二叉搜索树 538. 把二叉
     classSolution{public:TreeNode*trimBST(TreeNode*root,intlow,inthigh){if(root==nullptr)returnnullptr;if(root->val<l......
  • C++概述、选择结构、循环结构
    目录1C++概述1.1计算两个整数相加之和1.2计算三个整数相加之和2选择结构2.1小老鼠走迷宫1(if语句)2.2小老鼠走迷宫1(if语句)(多个单分支结构)2.3小老鼠走迷宫2(switch语句)2......
  • C++实战笔记(三)异常处理
    tags:C++Interview写在前面简单总结一下C++异常处理部分(Exception).异常只是C++为了处理错误提出的一种解决方案,并不是唯一的一种.异常处理特点异常处理的流程完全独立......
  • 2-sum 和 3-sum 问题的快速解法
    用科学方法分析程序中介绍了3-sum问题的暴力解法(ThreeSum)——用三个嵌套的for循环来求和为0的三元组个数,增长数量级为立方级别。类似地,对于2-sum问题(找出一个输入......