给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
- 节点的左子树只包含 小于 当前节点的数。
- 节点的右子树只包含 大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入:root = [2,1,3]
输出:true
示例 2:
输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。
提示:
树中节点数目范围在[1, 104] 内
-2^31 <= Node.val <= 2^31 - 1
首先,二叉树的实现是:
// Definition for a binary tree node
class TreeNode
{
public:
int val;
TreeNode *left;
TreeNode *right;
TreeNode()
{
this->val=0;
this->left=nullptr;
this->right=nullptr;
}
TreeNode(int x)
{
this->val=x;
this->left=nullptr;
this->right=nullptr;
}
TreeNode(int x,TreeNode *left,TreeNode *right)
{
this->val=x;
this->left=left;
this->right=right;
}
};
Method 1:
使用递归的方法验证二叉搜索树
Code 1:
class Solution{
public:
// 递归验证二叉搜索树
bool Recurve(TreeNode *root,long max,long min){
// 如果根节点为空
// 说明访问到了叶节点
if(root==nullptr){
// 返回True
return true;
}
// 如果根节点大于最大值或小于最小值
// 即不满足二叉搜索树节点大小的性质
if(root->val>=max||root->val<=min){
// 返回False
return false;
}
// 因为二叉搜索树的左右子树同样也是二叉搜索树
// 因此递归遍历左右子树
return Recurve(root->left,root->val,min)&&Recurve(root->right,max,root->val);
}
// 验证二叉搜索树
bool isValidBST(TreeNode *root){
// 递归验证二叉搜索树
return Recurve(root,LONG_MAX,LONG_MIN);
}
};
其中,由于给定条件:
-2^31 <= Node.val <= 2^31 - 1
因此,使用C++中的数值标识符来表示最大值和最小值。
C++中的数值标识符相关知识可见:
(Note)C++数值标识符_Think@的博客-CSDN博客
使用数值标识符需要提前调用< limits >头文件。
Method 2:
使用中序遍历递归的方法验证二叉搜索树
Code 2:
class Solution{
public:
// 递归进行中序遍历以验证二叉搜索树
bool Recurve(TreeNode *root,long &min){
// 如果根节点为空
// 则说明访问到了叶节点
if(root==nullptr){
// 返回True
return true;
}
// 递归遍历左子树
// 验证左子树是否为二叉搜索树
bool l=Recurve(root->left,min);
// 如果根节点小于左子树的最大值
if(root->val<=min){
// 则表明不满足二叉搜索树节点大小的性质
return false;
}
// 记录当前根节点的值
min=root->val;
// 递归遍历右子树
bool r=Recurve(root->right,min);
// 因为二叉搜索树的左右子树同样也是二叉搜索树
// 因此递归中序遍历以验证当前根节点的左右子树
return l&&r;
}
// 验证二叉搜索树
bool isValidBST(TreeNode *root){
// 记录当前的最小值
long min=LONG_MIN;
// 递归进行中序遍历
return Recurve(root,min);
}
};
Method 3:
使用栈进行中序遍历来验证二叉搜索树
Code 3:
class Solution{
public:
// 验证二叉搜索树
bool isValidBST(TreeNode *root){
// 记录当前的最小值
long min=LONG_MIN;
// 用栈来缓存进行中序遍历
stack<TreeNode *> temp;
// 如果栈不空或二叉搜索树没有遍历完毕
// 就继续循环
while(!temp.empty()||root!=nullptr){
// 如果没有遍历到叶子结点
while(root!=nullptr){
// 将当前节点入栈
temp.push(root);
// 在遍历到叶子结点之前持续遍历左子树
root=root->left;
}
// 将栈顶节点出栈
root=temp.top();
// 弹出栈顶节点
temp.pop();
// 如果根节点的值小于左子树的最大值
if(root->val<=min){
// 表明不满足二叉搜索树节点大小的性质
return false;
}
// 如果满足性质,更新左子树的最大值
min=root->val;
// 在遍历完左子树和根节点之后
// 转向遍历遍历右子树
root=root->right;
}
return true;
}
};
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/validate-binary-search-tree
Reference:
【LeetCode】【C++】98. 验证二叉搜索树_None072的博客-CSDN博客
(Note)C++数值标识符_Think@的博客-CSDN博客