1. 题目链接:98. 验证二叉搜索树
2. 题目描述:
给你一个二叉树的根节点
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
3. 解法(利用中序遍历):
中序遍历按照左子树->根节点->右子树的顺序遍历二叉树的所有节点,通常用于二叉搜索树相关的题目。
3.1 算法思路:
如果一棵树是二叉搜索树,那么它的中序遍历的结果一定是一个严格递增的序列
因此,我们可以初始化一个无穷小的全区白变量,用来记录中序过程中的前驱节点。那么就可以在中序遍历的过程中,先判断是否和前驱节点构成递增序列,然后修改前驱节点为当前节点,传入下一层的递归中。
3.2 算法流程:
- 初始化一个全局遍历
prev
,用来记录中序遍历过程中的前驱节点的val
- 中序遍历的递归函数中:
- 设置递归出口:
root==nullptr
的时候,返回true
; - 先递归判断左子树是否是二叉搜索树,用
retleft
标记 - 然后判断当前节点是否满足二叉树搜索树的性质,用
retcur
标记:- 如果当前节点的
val
大于prev
,说明满足条件,retcur
改为true
; - 如果当前节点的
val
小于等于prev
,说明不满足条件,retcur
改为false
;
- 如果当前节点的
- 最后递归判断右子树是否是二叉搜索树,用
retright
标记
- 设置递归出口:
- 只有当
retleft
、retcur
和retright
都是true
的时候,才返回true
3.3 C++算法代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
long prev=LONG_MIN;
public:
bool isValidBST(TreeNode* root) {
if(root==nullptr) return true;
bool left=isValidBST(root->left);
//剪枝
if(left==false) return false;
bool cur=false;
if(root->val>prev) cur=true;
//剪枝
if(cur==false) return false;
prev=root->val;
bool right=isValidBST(root->right);
//剪枝
if(right==false) return false;
return cur&&left&&right;
}
};