题目
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入:
2
/ \
1 3
输出: true
示例 2:
输入:
5
/ \
1 4
/ \
3 6
输出: false
解释: 输入为: [5,1,4,null,null,3,6]。
根节点的值为 5 ,但是其右子节点值为 4 。
- 方法一:利用二叉搜索树中序遍历序列有序的性质
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode *pre = NULL;//记录当前节点的前一个节点
bool isValidBST(TreeNode* root) {
if(root==NULL) return true;
if(!isValidBST(root->left)) return false;//递归求中序遍历序列
if(pre!=NULL && pre->val >=root->val) return false;//判断当前节点和它的前一个节点所存值的大小
pre = root;//更新pre的值
return isValidBST(root->right);
}
};
-
时间复杂度O(n)
-
空间复杂度O(logn)
-
思路
- 设置一个全局变量记录当前中序遍历节点的前一个节点。在递归求中序遍历序列中,判断当前节点的值是否大于其前一个节点,如果不是则返回false
-
方法二:利用二叉搜索树的定义递归
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool isValidBST(TreeNode* root, long long lower, long long upper) {
if(root==NULL) return true;//空节点返回true
//如果它不在当前的数据范围内则返回false
if(root->val<=lower || root->val>=upper) return false;
//递归判断其左子树,将upper改为当前节点的值
//递归判断其右子树,将lower改为当前节点的值
return isValidBST(root->left, lower, root->val) && isValidBST(root->right, root->val,upper);
}
bool isValidBST(TreeNode* root) {
return isValidBST(root, LONG_MIN, LONG_MAX);//起始的最小值和最大值分别为long的最小值和最大值,因为数据范围包括了int的最小值
}
};
- 时间复杂度O(n)
- 空间复杂度O(logn)
- 思路
- 二叉树需满足左子树只包含比当前节点小的数,右子树只包含比当前节点大的数,故传入参数时设置当前节点的范围,在后来的判断中更新节点范围即可。
- 如果不在范围内返回false,如果为空节点则返回false,否则递归判断其左右子树是否为二叉搜索树