题目:
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
解法1:由上而下,递归传入上下限
/**
* 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 {
private:
bool isValid(TreeNode* root, long lower, long higher) {
if (NULL == root)
return true;
if (root->val <= lower || root->val >= higher)
return false;
return isValid(root->left, lower, root->val) && isValid(root->right, root->val, higher);
}
public:
bool isValidBST(TreeNode* root) {
//return isValid(root, LONG_MIN, LONG_MAX);
return isValid(root, INT_MIN - 1L, INT_MAX + 1L);
}
};
这种解法会在子树中,逐步细化上下限。注意初始值的上下限。
尤其要注意上下限的数据类型,应该比int类型大,并且INT_MIN-1L中的L一定不可少!因为隐藏了数据类型转换!
将根节点拎出来单独处理,会比较好理解,具体如下:
class Solution {
public:
bool isValidSubBST(TreeNode *root, long left, long right) {
if (NULL == root)
return true;
if (root->val <= left || root->val >= right)
return false;
return isValidSubBST(root->left, left, root->val)
&& isValidSubBST(root->right, root->val, right);
}
bool isValidBST(TreeNode* root) {
if (NULL == root)
return true;
return isValidSubBST(root->left, INT_MIN-1l, root->val)
&& isValidSubBST(root->right, root->val, INT_MAX+1l);
}
};
解法2:递归中序遍历
class Solution {
private:
bool isValid(TreeNode* root, long& lower) {
if (NULL == root)
return true;
if (!isValid(root->left, lower))
return false;
if (root->val <= lower)
return false;
lower = root->val;
return isValid(root->right, lower);
}
public:
bool isValidBST(TreeNode* root) {
long lower = INT_MIN - 1L;
return isValid(root, lower);
}
};
解法3:用栈一直压入左子树
class Solution {
public:
bool isValidBST(TreeNode* root) {
if (NULL == root)
return true;
long lower = INT_MIN - 1L;
stack<TreeNode*> sta;
while (!sta.empty() || root) {
while (root) { //压入左子节点
sta.push(root);
root = root->left;
}
root = sta.top();
sta.pop();
if (root->val <= lower) //没有左子树时,就是左子节点和左子节点的父节点
return false;
lower = root->val;
root = root->right; //处理右子树
}
return true;
}
};