题目
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
思路
中序遍历下,二叉搜索树的节点数值是一个有序序列
即验证二叉搜索树相当于变成了判断一个序列是不是递增了
- 递归法
class Solution {
TreeNode max;
public boolean isValidBST(TreeNode root){
if(root == null){
return true;
}
//递归处理左子树
boolean left = isValidBST(root.left);
//如果不满足则返回false,这里要用if语句,不能直接返回
if(!left){
return false;
}
// 中序遍历,验证遍历的元素是不是从小到大,这里才是单层循环真正的逻辑
if(max != null && root.val <= max.val){//一直更新maxVal,一旦发现maxVal >= root.val,即当前最大的节点数值比新加入的节点数值还要大(违反了递增要求),则返回false
return false;
}
max = root;
//递归处理右子树
boolean right = isValidBST(root.right);
return right;//整个函数最终的返回语句
}
}
- 迭代法
用迭代法中序遍历稍加改动即可
class Solution {
public boolean isValidBST(TreeNode root){
if(root == null){
return true;
}
Stack<TreeNode> stack = new Stack<>();
TreeNode pre = null;
while(root != null || !stack.isEmpty()){//这个是最外层的判断条件,一个都不能少,并没有和下面的while循环里面的root判断重复,因为外层是大循环,内层是为了找到左下节点的循环
//这里的判断是为了找到最左下的节点
while(root != null){//只要节点不为空
stack.push(root);//就将节点一直入栈
root = root.left;//直到找到了最左下的左孩子
}
//中,处理逻辑,开始判断是否满足递增性质
TreeNode pop = stack.pop();//出当前栈顶元素
if(pre != null && pop.val <= pre.val){//pop的是中节点,和前驱节点pre比,如果中节点小于左孩子(前驱)节点说明不满足递增的序列
return false;
}
pre = pop;//指针后移,指向中节点
root = pop.right;//继续判断右边,用root和pre作比较
}
return true;
}
}