题目:
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.
二叉搜索树的定义如下:
根结点的左子树的所有结点的值小于根结点的值。
根结点的右子树的所有结点的值大于根结点的值。
左右子树也都是二叉搜索树。
思路:
递归判断,递归时传入两个参数,一个是左界,一个是右界,节点的值必须在两个界的中间,同时在判断做子树和右子树时更新左右界。
代码1:
/**
* Definition for binary tree
* 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 isValidBST(root,INT_MIN,INT_MAX);
}
bool isValidBST(TreeNode *root , int leftVal , int rightVal)
{
if(root == NULL )
return true;
return root->val > leftVal && root->val < rightVal
&& isValidBST(root->left,leftVal,root->val)
&& isValidBST(root->right,root->val,rightVal);
}
};
上面的代码有点bug,就是当root->val 为2147483647时,不能AC,改为LONG_MIN , LONG_MAX就可以了。
代码2:
由二叉搜索树的性质可知,中序遍历二叉树时,结果是按从小到大的顺序排列,因此可以先用中序遍历,再判断遍历结果是否有序即可。
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isValidBST(TreeNode *root)
{
if(root == NULL)
return true;
vector<int> result;
inorder(root,result);
for(int i = 0 ; i < result.size()-1 ; i++)
{
if(result[i] >= result[i+1])
return false;
}
return true;
}
void inorder(TreeNode *root , vector<int> &result)
{
if(root == NULL)
return;
inorder(root->left,result);
result.push_back(root->val);
inorder(root->right,result);
}
};
代码3:
在中序遍历时直接判断,只需保存下来当前结点的前一个结点即可。:
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isValidBST(TreeNode *root)
{
TreeNode *prev = NULL;
return isValidBST(root , prev);
}
bool isValidBST(TreeNode *root , TreeNode *&prev)
{
if(root == NULL)
return true;
//遍历左孩子
if(!isValidBST(root->left , prev))
return false;
//如果当前结点的中序遍历结果前面存在结点,但是值比当前值大,说明不是BST
if(prev != NULL && prev->val >= root->val)
return false;
//更新前一个结点
prev = root;
//遍历右孩子
return isValidBST(root->right , prev);
}
};