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.

This solution can also be written as the following:

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

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>

  1. Cong on 2014-3-18

    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.

  2. jhorwit on 2014-7-10

    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.

  3. jhorwit on 2014-7-10

    nvm

  4. XiY on 2014-9-28

    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.

  5. Laura on 2014-9-30

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

  6. Meijufan on 2014-11-15

    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.

  7. DonBear on 2014-12-22

    You are right.

  8. DonBear on 2014-12-22

    You are right.

  9. ryanlr on 2015-6-11

    problem is fixed.

  10. Shaurya Kalsi on 2015-7-12

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

  11. LZhu on 2015-8-25

    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

  12. Adrian on 2016-1-24

    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;
    }

  13. Gaurav Khurana on 2016-5-11

    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));
    }

  14. BruceLee on 2016-6-15

    it will not work for

    10

    /

    5 12

    /

    4 11

    which is NOT a valid BST, but your solution may return true,

  15. Rush on 2016-7-27

    BST can’t have duplicate values. Hence, while checking we include equal condition.

  16. Rush on 2016-7-27

    if(root.val=high) return false;

    ‘=’ in condition confirms that no node value appear more than once.

  17. Matias SM on 2016-8-7

    Note to avoid bad generalizations. A BST _can_ have duplicated values (if required). However, according to this exercise, it can’t (strict order is required as defined by the rules).

    “…Whether duplicates, i.e. different elements with same key, shall be allowed in the tree or not, does not depend on the order relation, but on the application only…”
    https://en.wikipedia.org/wiki/Binary_search_tree

  18. Matias SM on 2016-8-7

    A recursive implementation for any type (not restricted to numbers):


    boolean isBst(BinTreeNode root, Comparator cmp) {
    return isBst(root, Optional.empty(), Optional.empty(), cmp);
    }

    boolean isBst(BinTreeNode root, Optional minValue, Optional maxValue, Comparator cmp) {
    if (root == null) return true;
    if (minValue.map(min -> cmp.compare(root.value, min) > 0).orElse(Boolean.TRUE) &&
    maxValue.map(max -> cmp.compare(root.value, max) < 0).orElse(Boolean.TRUE))
    {
    return isBst(root.left, minValue, Optional.of(root.value), cmp) &&
    isBst(root.right, Optional.of(root.value), maxValue, cmp);
    }
    return false;
    }

  19. Udaydeep Thota on 2016-9-5

    If I want to validate the BST allowing duplicates in the tree (say right node can contain elements greater than or EQUAL to root, how could any of the recursive solution be modified ?

  20. Venk on 2016-12-17

    Nice One

  21. Stefanus Anggara on 2017-1-18

    where the difference between queue.add and queue.offer?
    what if I always use queue.add to insert new object to LinkedList?

  22. Birendra Singh on 2017-3-22

    My Recursive solution-
    static boolean validateBST(TreeNode root, boolean isValid)
    {

    if (isValid && root != null) {
    if ((root.leftNode != null && root.value root.rightNode.value)) {
    isValid = false;
    } else
    {
    isValid = true;
    }
    if (isValid ) {
    isValid =validateBST(root.leftNode,isValid);
    //}
    //if (isValid && root.value >= root.rightNode.value) {
    isValid =validateBST(root.rightNode,isValid);
    }
    }
    return isValid;
    }

  23. Birendra Singh on 2017-3-22

    here initial call would be validateBST(root,true)

Leave a comment

*