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:
At first I though it was a simple question: if the left and right subtrees are valid BST and root's number is bigger/smaller than the root of left/right subtree,then it is a valid BST.
But this is wrong.
Suppose we have a valid BST
2
/ \
1 3
and we make this as a subtree of a root 3
3 / 2 / \ 1 3
Even though [2,1,3] is a valid BST and the old root 2 < the new root 3, the new BST is not a valid BST. This is because the leaf node 3 is in the left subtree.
This tells us that the new root should be compared to all of its nodes in its subtree instead of only its left/right child. Thus my first though is wrong.
But if we try to compare a node to all of nodes in its subtrees, the complexity is exponential.
Lets make it in another way.
Suppose we have a BST.
INT_MIN 5 INT_MAX / \ 2 9 / \ / \ 0 3 7 11 / / 6 10If a BST is a valid BST, every node should fall in a range set by its precedents. Say 0 falls in [int_min, 2]. 2 falls in [int_min, 5]. 3 falls in [2,5]. 5 falls in [int_min, int_max]. 6 falls in [5,7]. 7 falls in [5,9]. 9 falls in [5, int_max]. 10 falls in [9,11]. 11 falls in [9, int_max].
If a BST is not a valid bST, there would be 1 node falling out of the range set by its precedents. The following is an invalid BST where 6(!) falls out of the range [2, 5].
5 / \ 2 9 / \ / \ 0 6(!) 7 11 / / 6 10One node's range is set by its precedents, and this node's val would set the range for nodes in lower level of its subtree.
Thus when we are at a node,
1. we check if this node is in its range [low, high]
2. If 1 is true, then we go check this node's left subtree, by setting the range for the left subtree [low, node->val-1]. After we check the leftsubtree we go check the right subtree, by setting the range for the right substree [node->val+1, high].
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isValidBST(TreeNode* root) {
return validBST(root, INT_MIN, INT_MAX);
}
bool validBST(TreeNode *node, int lower, int higher){
if(!node) return true;
if(node->val == INT_MIN && node->left || node->val == INT_MAX && node->right) return false;
if(lower>higher || node->val < lower || node->val > higher) return false;
if(validBST(node->left, lower, node->val - 1) && validBST(node->right, node->val+1, higher)) return true;
else return false;
}
};