LeetCode Top 100 Liked Questions 98. Validate Binary Search Tree (Java版; Medium)

welcome to my blog

LeetCode Top 100 Liked Questions 98. Validate Binary Search Tree (Java版; Medium)

题目描述
Given a binary tree, determine if it is a valid binary search tree (BST).

Assume a BST is defined as follows:

The left subtree of a node contains only nodes with keys less than the node's key.
The right subtree of a node contains only nodes with keys greater than the node's key.
Both the left and right subtrees must also be binary search trees.


Example 1:

    2
   / \
  1   3

Input: [2,1,3]
Output: true
Example 2:

    5
   / \
  1   4
     / \
    3   6

Input: [5,1,4,null,null,3,6]
Output: false
Explanation: The root node's value is 5 but its right child's value is 4.

class Solution {
    public boolean isValidBST(TreeNode root) {
        if(root==null){
            return true;
        }
        Stack<TreeNode> s = new Stack<>();
        TreeNode cur = root;
        long pre = Long.MIN_VALUE;
        while(cur!=null || !s.isEmpty()){
            if(cur!=null){
                s.push(cur);
                cur = cur.left;
            }else{
                cur = s.pop();
                if(cur.val <= pre){
                    return false;
                }
                pre = cur.val;
                cur = cur.right;
            }
        }
        return true;
    }
}
第一次做; 可以改成循环版的中续遍历, 其余思想和下面的方法一致
//循环版中序遍历
import java.util.Stack;

class Solution {
    public boolean isValidBST(TreeNode root) {
        Stack<TreeNode> s = new Stack<>();
        TreeNode curr =root;
        long pre = Long.MIN_VALUE;
        while(!s.isEmpty() || curr!=null){
            //一路将左节点压栈
            while(curr!=null){
                s.push(curr);
                curr = curr.left;
            }
            //直到没有左节点,弹出栈顶元素
            curr = s.pop();
            if(curr.val <= pre)
                return false;
            //here, curr.val > pre
            //update
            pre = curr.val;
            //令curr指向curr.right, 看看curr有没有右子树, 有的话就得一路将curr.right的左孩子们压栈
            curr = curr.right;
        }
        return true;
    }
}
第一次做; 中续遍历二叉树, 将当前节点的值和便利过程中的前一个值pre比较, 当前节点的值大于pre的话, 就更新pre, 继续遍历; 当前节点的值小于等于pre的话, 返回false; 细节:一开始我用的Integer.MIN_VALUE(等于-2147483648)作为pre的初始值, 结果没有通过, 因为有一个案例的输入是[-2147483648], 这个节点的值等于pre, 所以返回false, 但是应该返回true; 犹豫TreeNode的定义中val是int类型的, 所以我把pre的初始值改成了Long.MIN_VALUE(等于-2^63); 如果节点定义中val是long类型的呢? 其实第一步可以先找到中序遍历中的第一个节点作为pre的初始值, 然后从中续遍历的第二个节点开始与pre比较; 中续遍历可以改成循环版的
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public Long pre = Long.MIN_VALUE; // 有一个输入是[-2147483648], 
    //递归逻辑: 以当前节点为根的二叉树是否为搜索二叉树
    public boolean isValidBST(TreeNode root) {
        //input check 
        if(root==null)
            //和面试官商量
            return true;
        boolean res=false;
        //以当前节点的左孩子(新条件新递归)为根的二叉树是否为搜索二叉树
        res = isValidBST(root.left);
        if(res==false)
            return false;
        //处理当前输入
        //如果当前节点的值小于等于pre, 则返回false
        if(root.val <= pre)
            return false;
        //如果当前节点的值大于pre, 则更新pre
        pre = (long)root.val;
        //以当前节点的右孩子(新条件新递归)为根的二叉树是否为搜索二叉树
        res = isValidBST(root.right);
        return res;
    }
}
题解, 针对左子树设置上界, 针对右子树设置下界; 最开始我也想着用类似的方法做, 但是没想到怎么设置界限, 也没想到需要设置上下界; 更没想到需要对左子树设置上界, 对右子树设置下界; 看图就知道为什么需要上下界了

下图不是搜索二叉树, 因为右子树有一个节点的val小于根节点的val, 事实上, 右子树所有节点的val都应该大于根节点的val

原图链接

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);
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值