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 3Binary tree
[2,1,3]
, return true.
Example 2:
1 / \ 2 3Binary tree
[1,2,3]
, return false.Solution:
Method 1: in-order traverse
We use non-iterative in-order traversal to go through the BST.
The property of a BST is the in-order sequence of the elements is in ascending order.
Therefore we just need one pass of the traversal and check if each of the node is equal or larger than the previous one.
Both the time complexity and space complexity are O(n).
Code:
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public boolean isValidBST(TreeNode root) { if (root == null) { return true; } Stack<TreeNode> stack = new Stack<>(); TreeNode prev = null; while (root != null || !stack.isEmpty()) { while (root != null) { stack.push(root); root = root.left; } root = stack.pop(); if (prev != null && root.val <= prev.val) { return false; } prev = root; root = root.right; } return true; } }
Method 2: Divide & Conquer
For each node, we need to make sure all its left subtree are smaller than itself and all its right subtree are larger than itself.
Notice we use Integer instead of int so that we can use null.
Code:
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public boolean isValidBST(TreeNode root) { return helper(root, null, null); } public boolean helper(TreeNode root, Integer min, Integer max) { if (root == null) { return true; } if ((min != null && root.val <= min) || (max != null && root.val >= max)) { return false; } return helper(root.left, min, root.val) && helper(root.right, root.val, max); } }