LeetCode – Validate Binary Search Tree (Java)

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.

Java Solution 1 - Recursive

All values on the left sub tree must be less than root, and all values on the right sub tree must be greater than root. So we just check the boundaries for each node.

public boolean isValidBST(TreeNode root) {
    return isValidBST(root, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);    
}
 
public boolean isValidBST(TreeNode p, double min, double max){
    if(p==null) 
        return true;
 
    if(p.val <= min || p.val >= max)
        return false;
 
    return isValidBST(p.left, min, p.val) && isValidBST(p.right, p.val, max);
}

This solution also goes to the left subtree first. If the violation occurs close to the root but on the right subtree, the method still cost O(n). The second solution below can handle violations close to root node faster.

Java Solution 2 - Iterative

public class Solution {
    public boolean isValidBST(TreeNode root) {
        if(root == null)
            return true;
 
        LinkedList<BNode> queue = new LinkedList<BNode>();
        queue.add(new BNode(root, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
        while(!queue.isEmpty()){
            BNode b = queue.poll();
            if(b.n.val <= b.left || b.n.val >=b.right){
                return false;
            }
            if(b.n.left!=null){
                queue.offer(new BNode(b.n.left, b.left, b.n.val));
            }
            if(b.n.right!=null){
                queue.offer(new BNode(b.n.right, b.n.val, b.right));
            }
        }
        return true;
    }
}
//define a BNode class with TreeNode and it's boundaries
class BNode{
    TreeNode n;
    double left;
    double right;
    public BNode(TreeNode n, double left, double right){
        this.n = n;
        this.left = left;
        this.right = right;
    }
}
Category >> Algorithms  
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
<pre><code> 
String foo = "bar";
</code></pre>
  • Gaurav Khurana

    I think it could be simply

    public bool ValidateBST(Node node)
    {
    if (node == null)
    {
    return true;
    }

    if ((node.Left != null && node.Left.Value > node.Value) || (node.Right != null && node.Right.Value < node.Value))
    {
    return false;
    }

    return (ValidateBST(node.Left) && ValidateBST(node.Right));
    }

  • Adrian

    For iterative solution how about inorder tree traversal and compere its previous value with current node? Following code is in C#.

    public bool IsBST(TreeNode root)
    {
    Stack s = new Stack();
    TreeNode p = root;
    int? nVal = null; // previous value

    while (s.Count != 0 || p != null)
    {
    if (p != null)
    {
    s.Push(p);
    p = p.left;
    }
    else
    {
    TreeNode node = s.Pop();
    p = node.right;
    if (nVal != null && nVal > node.val)
    return false;
    nVal = node.val;
    }
    }
    return true;
    }

  • if i was right,
    it should be “if(p.val = max) return false;”

    Property of the BST: all left descendents <= n < right descendents, for each node n

  • Shaurya Kalsi

    why isn’t it if(p.val max). Why do we also exclude it when it is equal?

  • ryanlr

    problem is fixed.

  • DonBear

    You are right.

  • DonBear

    You are right.

  • I think the algorithm will fail if the tree is a single node with the root value set to Integer.MIN_VALUE or Integer.MAX_VALUE. I think we should define min and max to double or long to be safe.

  • Laura

    Does this fail because it never checks that the keys are unique? Requirement for BST is that the keys are unique.

  • XiY

    solution is right
    Through validate(root.left, min, root.val), in the “5” level, max is root.val which is 10 in your example, when you move deeper to the next recursion, the value of max in validate(root.right, root.val, max) is exact root.val which = 10, that is out of the range and return false.

  • jhorwit

    nvm

  • jhorwit

    This solution will not work. Imagine a tree:

    10
    /
    5 12
    /
    4 11

    The method above will return true since 11 is greater than 5; however, 11 is greater than 10 so it should be in the right subtree from root.

  • Cong

    Hey, I think you should evaluate the keys of the root, its left and right children first, before you go down to the recursion. The current version will always return true.