给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
-
节点的左子树只包含 小于 当前节点的数。 -
节点的右子树只包含 大于 当前节点的数。 -
所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入:root = [2,1,3]
输出:true
示例 2:
输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。
提示:
Related Topics
树
深度优先搜索
二叉搜索树
二叉树
思路1:非递归深度中序遍历
参考非递归的中序遍历,在每一次遍历的时候,跟前一个值比较大小。
class Solution {
? ?public boolean isValidBST(TreeNode root) {
? ? ? ?//中序非递归遍历二叉树 和前一个值进行比较
? ? ? ?Deque<TreeNode> stack = new LinkedList<>();
? ? ? ?List<Integer> list = new ArrayList<>();
?
? ? ? ?TreeNode p = root;
? ? ? ?while (p!= null || !stack.isEmpty()){
? ? ? ? ? ?if(p!=null){
? ? ? ? ? ? ? ?stack.push(p);
? ? ? ? ? ? ? ?p = p.left;
? ? ? ? ? }else{
? ? ? ? ? ? ? ?p = stack.pop();
? ? ? ? ? ? ? ?//跟前一个比较 必须大于前一个值 但由于第一个元素前面没有值 必须保证下标
? ? ? ? ? ? ? ?if(list.size()>0&& list.get(list.size()-1) >= p.val){//不符合
? ? ? ? ? ? ? ? ? ?return false;
? ? ? ? ? ? ? }
? ? ? ? ? ? ? ?list.add(p.val);
? ? ? ? ? ? ? ?p = p.right;
? ? ? ? ? }
? ? ? }
? ? ? ?return true;
? }
}
解答成功:
执行耗时:3 ms,击败了18.39% 的Java用户
内存消耗:41.4 MB,击败了5.09% 的Java用户
可以把集合改成一个最小值min记录。
public boolean isValidBST(TreeNode root) {
? ?//中序非递归遍历二叉树 和前一个值进行比较
? ?Deque<TreeNode> stack = new LinkedList<>();
? ?long min = Long.MIN_VALUE;
?
? ?TreeNode p = root;
? ?while (p!= null || !stack.isEmpty()){
? ? ? ?if(p!=null){
? ? ? ? ? ?stack.push(p);
? ? ? ? ? ?p = p.left;
? ? ? }else{
? ? ? ? ? ?p = stack.pop();
? ? ? ? ? ?//跟前一个比较 必须大于前一个值 但由于第一个元素前面没有值 必须保证下标
? ? ? ? ? ?if(min >= p.val){//不符合
? ? ? ? ? ? ? ?return false;
? ? ? ? ? }
? ? ? ? ? ?min = p.val;
? ? ? ? ? ?p = p.right;
? ? ? }
? }
? ?return true;
}
解答成功:
执行耗时:1 ms,击败了28.67% 的Java用户
内存消耗:41.4 MB,击败了5.09% 的Java用户
思路2:递归
根据当前值,确定左子树中值的范围,在递归中根据值的范围判断是否符合。
class Solution {
? ?public boolean isValidBST(TreeNode root) {
? ? ? ?return isValidBST(root,Long.MIN_VALUE,Long.MAX_VALUE);
? }
? ?//(low,high)为这颗树的范围 这个树种的值都必须满足 low < val < high
? ?//low high为long型是因为测试用例有整型最小值 测试用例:[-2147483648]
? ?public boolean isValidBST(TreeNode root,long low,long high){
? ? ? ?if(root == null){
? ? ? ? ? ?return true;
? ? ? }
? ? ? ?if(root.val <= low || root.val >= high){
? ? ? ? ? ?return false;
? ? ? }
? ? ? ?//左子树中值的范围是 (low,当前节点的值)
? ? ? ?//右子树中值的范围是(当前节点的值,high)
? ? ? ?return isValidBST(root.left,low,root.val) && isValidBST(root.right,root.val,high);
? }
}
|