标签:roo div private leetcode amp code etc 上下 关系
中序。
刚拿到题目时,第一想法是递归,但是搞错了二叉搜索树成立的条件。
我以为的条件是:左侧树为二叉搜索树,右侧树为二叉搜索树,且root.right>root>root.left,然后递归。
但是显然这不对,满足以上条件后,root.right.left可能比root要小。
先说正确的递归解法:
正确的条件是:
后两个条件可以转化为更好写代码的两个条件:
抽象为这个图
递归函数: helper(root,lower,upper)
递归函数的作用:以root为根节点的树,满足lower和upper的上下界限制
终止条件:1.当前节点时叶子节点,返回true 2.当前节点本身已经不满足[lower,upper]的上下界限制,返回false
递归关系:以root为根节点的树满足lower和upper的上下界要求的条件是:首先root得满足[lower,upper]的上下界限制,其次root.left需满足[lower,root.val]的上下界要求,且root.right满足[root.val,upper]的上下界要求
这个递归关系用语言描述起来感觉很模糊,但是对照着上一张图看起来就很清晰了。
class Solution { public boolean helper(TreeNode node, Integer lower, Integer upper) { if (node == null) return true; int val = node.val; if (lower!=null && val <= lower) return false; if (upper!=null && val >= upper) return false; if (! helper(node.right, val, upper)) return false; if (! helper(node.left, lower, val)) return false; return true; } public boolean isValidBST(TreeNode root) { return helper(root, null, null); } }
代码有几处需要注意:
所以这个解法真的好多坑啊。。。
下一种最容易看懂的方式,是以递归实现中序遍历,把二叉树的值中序遍历存到一个List里,然后检查这个List是否是升序的就行了
class Solution { List<Integer> res = new ArrayList<>(); public boolean isValidBST(TreeNode root) { if(root==null) return true; inOrder(root); for(int i=1;i<res.size();i++){ if(res.get(i)<=res.get(i-1)){ return false; } } return true; } private void inOrder(TreeNode root){ if(root!=null){ inOrder(root.left); res.add(root.val); inOrder(root.right); } } }
这种解法无比容易看懂,且时间复杂度是On,空间复杂度是On。但是当然还是要慢一些,如果直接通过迭代的方式实现中序遍历(压栈),就可以在遍历的过程中进行检测了。或者也可以通过递归的方式实现中序遍历,并在其中做判断:
class Solution { long pre = Long.MIN_VALUE; public boolean isValidBST(TreeNode root) { if (root == null) { return true; } // 访问左子树 if (!isValidBST(root.left)) { return false; } // 访问当前节点:如果当前节点小于等于中序遍历的前一个节点,说明不满足BST,返回 false;否则继续遍历。 if (root.val <= pre) { return false; } pre = root.val; // 访问右子树 return isValidBST(root.right); } }
这样很巧妙,但是更难理解一些。。。
LeetCode 树 98. 验证二叉搜索树(二叉搜索树,递归,中序遍历,迭代)
标签:roo div private leetcode amp code etc 上下 关系
原文地址:https://www.cnblogs.com/take-it-easy/p/13336271.html