验证二叉搜索性
力扣98:https://leetcode.cn/problems/validate-binary-search-tree/
题干:
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
节点的左子树只包含 小于 当前节点的数。
节点的右子树只包含 大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
思路:
-
本题的直观想法可能上来就是站在一个节点上看这个节点的值是不是比它的左子树的节点值更大,并且还要比它的右子树的节点值更小,如果二者都满足,则说明,当前节点检查完毕,那就可能写出错误代码:
class Solution { public boolean isValidBST(TreeNode root) { if(root==null) return true; boolean leftRes = true; boolean rightRes = true; if(root.left==null){ //不用对leftRes做什么修改 }else{ if(root.left.val>=root.val){ leftRes=false; } } if(root.right==null){ //不用对rightRes做什么修改 }else{ if(root.right.val<=root.val){ rightRes=false; } } if(leftRes==false||rightRes==false) return false; return isValidBST(root.left)&&isValidBST(root.right); } }
如上图,虽然每个节点的值都能在遍历过程中通过检查,但是节点值为5的节点,显然比它的右子树中的节点值为4的节点值更小,这显然不符合二叉搜索树的定义.
-
思路2:
因为我们知道二叉搜索树的中序遍历可以得到升序遍历结果,所以我们只需要把此时的二叉树进行中序遍历,如果遍历结果符合升序排序,则说明当前的二叉树就是二叉搜索树
class Solution { ArrayList<Integer> list = new ArrayList<>(); public boolean isValidBST(TreeNode root) { if(root==null) return true; inTraverse2(root); for(int i=0;i<list.size();i++){ if(i+1<list.size()&&list.get(i+1)<=list.get(i)){ return false; } } return true; } private void inTraverse2(TreeNode root){ if(root==null) return; inTraverse2(root.left); list.add(root.val); inTraverse2(root.right); } }
-
思路三:比较推荐
所以我们可以根据上图的思路,写出递归解法,即dfs:
class Solution { public boolean isValidBST(TreeNode root) { return dfs(root,-Long.MAX_VALUE,Long.MAX_VALUE); } private boolean dfs(TreeNode root,long min,long max){ if(root==null) return true; if(root.val>=max||root.val<=min) return false; return dfs(root.left,min,root.val)&&dfs(root.right,root.val,max); } }
代码清晰优雅.