递归版本
public boolean isValidBST(TreeNode root) {
return range(root,Integer.MIN_VALUE-1L,Integer.MAX_VALUE+1L);
}
public boolean range(TreeNode node,long min,long max){
if (node==null) return true;
if (node.val<=min||node.val>=max) return false;
return range(node.left,min,node.val)&&range(node.right,node.val,max);
}
错误思路:
在说正确思路前,我先说一下自己踩的坑,我本来想着只要递归,然后判断左节点的值如果大于等于根节点或者右结点的值小于等于根节点,就返回false,但是实际上这样子是不行的,请看下图
7 / \ 2 5 / \ 1 9
根据上面的思路得出的结果为true,这是因为忽略了左子树有上限,而右子树有下限导致的错误
正确思路:
利用上下限来进行判断
- 由于根节点没有上下限,所以使用变量类型所能存储的最大值和最小值作为上下限
- 如果该节点为null直接返回true
- 如果节点不为null,且节点值不在上下限规定的区间内,return false
- 继续判断子树,但要注意,左子树的上限为当前子树的值,右子树的下限是当前子树的值
迭代版本
public boolean isValidBST(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
TreeNode node = root;
long prev = Integer.MIN_VALUE-1L;
while (!stack.isEmpty()||node!=null){
while (node!=null){
stack.push(node);
node = node.left;
}
node = stack.pop();
if (node.val<=prev) return false;
prev = node.val;
node = node.right;
}
return true;
}
思路:
BSTree的中序遍历中,前一个被遍历的节点值必定要小于下一个要遍历的节点值,所以增加了一个存储前一个被遍历节点值的prev变量用作比较
这个方案是基于已经了解中序遍历的迭代方式的基础上进行讲解的,如果有小伙伴不了解,并且想要详细了解中序遍历迭代的讲解思路的,可以点击这里跳转