98. 验证二叉搜索树
给你一个二叉树的根节点
root
,判断其是否是一个有效的二叉搜索树。有效 二叉搜索树定义如下:
- 节点的左
- 只包含 小于 当前节点的数。
- 节点的右子树只包含 大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入:root = [2,1,3] 输出:true示例 2:
输入:root = [5,1,4,null,null,3,6] 输出:false 解释:根节点的值是 5 ,但是右子节点的值是 4 。提示:
- 树中节点数目范围在
[1, 104]
内-231 <= Node.val <= 231 - 1
性质解法
二叉搜索树的中序遍历为一个有序序列!
解法一:vector存储
使用vector进行中序存储,最后再对vector进行一次遍历。
缺点:空间复杂度较大
class Solution {
public:vector<int> res;bool isValidBST(TreeNode* root) {_Inorder(root);for(int i = 0; i < res.size()-1; i++)if(res[i] >= res[i+1])return false;return true;}void _Inorder(TreeNode* root){if(root == nullptr)return;_Inorder(root->left);res.push_back(root->val);_Inorder(root->right);}
};
解法二: 全局变量
可以使用一个全局变量pre来记录中序遍历当前位置之前结点大小。
class Solution {
public:long long pre = LLONG_MIN;bool isValidBST(TreeNode* root) {if(root == nullptr)return true;bool left = isValidBST(root->left);if(root->val <= pre)return false;elsepre = root->val;bool right = isValidBST(root->right);return left && right;}
};
剪枝
当我们左子树不是二叉搜索树时,就没有必要继续再看右子树情况了,所以下方这边进行了剪枝操作
class Solution {
public:long long pre = LLONG_MIN;bool isValidBST(TreeNode* root) {if(root == nullptr)return true;bool left = isValidBST(root->left);if(!left || root->val <= pre) // 进行剪枝return false;pre = root->val;return isValidBST(root->right);}
};