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
Binary tree [2,1,3], return true.
Example 2:
1
/ \
2 3
Binary tree [1,2,3], return false.
算法
dfs
o(n)
中序遍历是递增
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
//中序递增
struct TreeNode{
int val;
TreeNode * left;
TreeNode * right;
TreeNode(int x):val(x),left(NULL),right(NULL){}
};
class Solution {
public:
bool isValidBST(TreeNode* root) {
//travel the tree by inner-order
vector<TreeNode*> stack;
TreeNode* node=root;
vector<int> v;
while(stack.size()>0||node!=NULL){
if(node!=NULL){
stack.push_back(node);
node=node->left;
}else{
node=stack.back();
stack.pop_back();
v.push_back(node->val);
node=node->right;
}
}
//check the vector wether sorted or not
for(int i=0;v.size()>0**i<v.size()-1;i++){
if(v[i]>=v[i+1])
return false;
}
return true;
}
};
/*
* public class ValidateBinarySearchTree {
static class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
static class NodeWrapper{
TreeNode node;
}
public boolean isValidBST(TreeNode root) {
return helper(root, new NodeWrapper());
}
boolean helper(TreeNode root, NodeWrapper pre){
if(root == null)
return true;
if(!helper(root.left, pre))
return false;
//判断当前节点和上一个节点是否是有序的
if(pre.node != null && root.val <= pre.node.val) return false;
pre.node = root;
return helper(root.right, pre);
}
public static void main(String args[]){
TreeNode root = new TreeNode(7);
root.left = new TreeNode(5);
root.right = new TreeNode(10);
root.left.left = new TreeNode(3);
root.left.right = new TreeNode(6);
root.right.left = new TreeNode(9);
root.right.right = new TreeNode(12);
ValidateBinarySearchTree v = new ValidateBinarySearchTree();
System.out.println(v.isValidBST(root));
}
}
* */
TreeNode* createTree(int a[],int n){
if(n<=0)
return NULL;
TreeNode **tree=new TreeNode*[n];
for(int i=0;i<n;i++){
if(a[i]==0){
tree[i]=NULL;
continue;
}
tree[i]=new TreeNode(a[i]);
}
int pos=1;
for(int i=0;i<n&&pos<n;i++){
if(tree[i]){
tree[i]->left=tree[pos++];
if(pos<n)
tree[i]->right=tree[pos++];
}
}
return tree[0];
}
int main(){
Solution st;
cout<<st.isValidBST(NULL)<<endl;
int a[]={1,1};
cout<<st.isValidBST(createTree(a,sizeof(a)/sizeof(int)));
int b[]={4,2,6,1,7,5,7};
cout<<st.isValidBST(createTree(b,sizeof(b)/sizeof(int)));
int c[]={4,2,6,1,3,5,7};
cout<<st.isValidBST(createTree(c,sizeof(c)/sizeof(int)));
return 0;
}
算法
根据定义递归判断
结点node的左子树所有结点的值都小于node的值。
结点node的右子树所有结点的值都大于node的值。
结点node的左右子树同样都必须是二叉搜索树。
以下面的树为例,虽然tree(1)是合法的二分查找树,但是6小于10, 6所在的位置应该是位于 10~15之间,所以这棵树是不合法的。也就是说,需要两个值maxValue, minValue 来记录当前节点应该的取值范围。
10 ----- binary tree (0)
/ \
5 15 -------- binary tree (1)
/ \
6 20
class Solution {
private:
bool dfs(TreeNode *root, long long minval, long long maxval) {
if (root == NULL)
return true;
return root->val > minval &&
root->val < maxval &&
dfs(root->left, minval, root->val) &&
dfs(root->right, root->val, maxval);
}
public:
bool isValidBST(TreeNode *root) {
return dfs(root, (long long)INT_MIN - 1, (long long)INT_MAX + 1);
}
};