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.
[code lang="java"]
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isValidBST(TreeNode root) {
}
}
[code]
Idea – 1
val of every node must be within a range. For any bst , root's val must be in
[code lang="java"]
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isValidBST(TreeNode root) {
return isValidBST(root, null, null);
}
private boolean isValidBST(TreeNode x, Integer min, Integer max)
{
if(x == null)
{
return true;
}
boolean biggerThanMin = (min == null) || (min < x.val);
boolean smallerThanMax = (max == null) || (x.val < max);
return biggerThanMin
&& smallerThanMax
&& isValidBST(x.left, min, x.val)
&& isValidBST(x.right, x.val, max);
}
}
[code]
Runtime: 0 ms, faster than 100.00% of Java online submissions for Validate Binary Search Tree.Memory Usage: 37.8 MB, less than 94.08% of Java online submissions for Validate Binary Search Tree.
Idea – 2
Instead of putting pressure on thread's stack space (through recursion), we could use an explicit (heap-allocated) stack and do it iteratively. Asymptotic complexities remain unchanged.
[code lang="java"]
class Solution {
class StackItem
{
TreeNode x;
Integer min;
Integer max;
public StackItem(TreeNode x, Integer min, Integer max)
{
this.x = x;
this.min = min;
this.max = max;
}
public boolean biggerThanMin()
{
return (this.min == null) || (x.val > this.min);
}
public boolean smallerThanMax()
{
return (this.max == null) || (x.val < this.max);
}
}
public boolean isValidBST(TreeNode root) {
if(root == null)
{
return true;
}
Deque<StackItem> stack = new ArrayDeque<>();
stack.addLast( new StackItem(root, null, null) );
while(!stack.isEmpty())
{
StackItem top = stack.removeLast();
if(!top.biggerThanMin() || !top.smallerThanMax())
{
return false;
}
if(top.x.left != null)
{
stack.addLast( new StackItem(top.x.left, top.min, top.x.val) );
}
if(top.x.right != null)
{
stack.addLast( new StackItem(top.x.right, top.x.val, top.max) );
}
}
return true;
}
}
[code]
Runtime: 2 ms, faster than 23.79% of Java online submissions for Validate Binary Search Tree.Memory Usage: 38.6 MB, less than 76.26% of Java online submissions for Validate Binary Search Tree.