题目:
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入:
2
/ \
1 3
输出: true
示例 2:
输入:
5
/ \
1 4
/ \
3 6
输出: false
解释: 输入为: [5,1,4,null,null,3,6]。
根节点的值为 5 ,但是其右子节点值为 4 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/validate-binary-search-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
拓展:BST概念
BST(Binary Search Tree)目的是为了提高查找的性能,其查找在平均和最坏的情况下都是logn级别,接近二分查找。
其特点是:每个节点的值大于其任意左侧子节点的值,小于其任意右节点的值。左 < 中 < 右。
BST常见操作参考:https://blog.csdn.net/c_living/article/details/81021510
https://blog.csdn.net/stpeace/article/details/9067029
源码
/**
* Probelem:验证二叉搜索树
*
* @author:Gallery
*/
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
};
/**
* 思路一:利用中序遍历LNR+二叉搜索树的特点。
* 如果是正确的BST,则中序遍历树后的结果应该是有序的。
* 时间复杂度O(N)
* 空间复杂度O(N)/O(1)
* O(N):将遍历后结果保存一个数组中,最后在遍历一次(不好
* O(1):不用保存遍历结果,添加一个比较即可
* 思路二:利用上下边界
*
对于树的每个节点 val ,设其上下边界 low , high。(用 long 防止 INT_MAX 溢出 )
判断根结点时,须满足 low < val < high ,否则返回 false
判断左节点时,仅 上界 变化 ( 新上界为 high 与 val 较小值。又因 val 必小于 high,故新上界为 val )
判断右节点时,仅 下界 变化 ( 同理,新下界为 val )
*
*/
思路一代码:O(1)空间复杂度,
///我本地测试是可以通过,在线自定义案例结果也正确...提交后死活不行,留在这,希望有大佬知道为啥给我知道一下
//注:LONG_MIN和LONG_MAX些都被定义在limits.h中。leetcode应该是自动导入了这个库,所以可以直接用。
long long min = LONG_MIN;
bool isValidBST(struct TreeNode* root){
//判空
if(root == NULL){
return true;
}
//访问左子树
if(!isValidBST(root->left)){
return false;
}
//访问当前节点:若小于中序遍历前一个节点则不满足BST返回false
if(root->val <= min){
return false;
}
//若满足条件,则把min设置为当前节点
min = root->val;
//访问右子树
return isValidBST(root->right);
}
///思路一代码:空间复杂度o(n)
int * res = (int*)malloc(sizeof(int)*1000);//用于存储中序遍历结果
int res[10000];
int counter = 0;
void LRN(struct TreNode* root){
if(root!=NULL){
LRN(root->left);
res[counter++] = root->val;
LRN(root->right);
}
}
bool isValidBST(struct TreeNode* root){
if(root == NULL){
return true;
}
//中序遍历
LRN(root);
//遍历数组,判定是否合法
for(int i = 1;i < counter;++i){
if(res[i]<=res[i-1]){
return false;
}
}
return true;
}
///思路二代码:利用上下限
//注:LONG_MIN和LONG_MAX些都被定义在limits.h中。leetcode应该是自动导入了这个库,所以可以直接用。
///judge函数用于对比
bool judge(struct TreeNode*root, long min,long max){
if(root == NULL){
return true;
}
long num = root->val;
if(num <= min || num>=max){
return false;
}
return judge(root->left,min,num)&&judge(root->right,num,max);
}
bool isValidBST(struct TreeNode* root){
return judge(root, LONG_MIN, LONG_MAX);
}