Several solutions exist, which differ in terms of their space and time complexity.
One straight solution is to use the property of the BST. The results of the inorder traversal of the BST are sorted. Thus we can write the code with a little modification of the inorder traversal.
class Solution {
public:
bool isValidBST(TreeNode *root) {
vector<int> nodes;
inorder(nodes,root);
for(int i=1;i<nodes.size();i++){ //size_t是unsign类型的,失策了!
if(nodes[i-1]>=nodes[i])
return false;
}
return true;
}
void inorder(vector<int>& nodes, TreeNode* root){
if(root==NULL) return;
if(root->left) inorder(nodes, root->left);
nodes.push_back(root->val);
if(root->right) inorder(nodes, root->right);
}
};
This solution need O(n) space. We can reduce the space complexity by using the recursion or the iterative way, just adding the auxiliary variable, which stores the last visited node in the inorder traversal.
class Solution {
public:
bool isValidBST(TreeNode *root) { //a extra function to initialize pre
if(root==NULL) return true;
pre=numeric_limits<int>::min();
return isValid(root);
}
bool isValid(TreeNode *root){
if(root==NULL) return true;
if(isValid(root->left)){
if(pre<root->val){
pre=root->val;
return isValid(root->right);
}
}
return false;
}
private:
int pre; //auxiliary variable
};
Following is the iterative version.
class Solution {
public:
bool isValidBST(TreeNode *root) {
if(root==NULL) return true;
pre=numeric_limits<int>::min();
int res=true;
while(root){
if(root->left){
TreeNode *cur=root->left;
while(cur->right && cur->right!=root){
cur=cur->right;
}
if(cur->right){ //the left subtree is visited
if(pre>=root->val)
res=false;
pre=root->val; //almost forget
cur->right=NULL;
root=root->right;
}
else{
cur->right=root;
root=root->left;
}
}
else{
if(pre>=root->val) //the left subtree is visited
res=false;
pre=root->val;
root=root->right;
}
}
return res;
}
private:
int pre;
};