leetcode 98验证二叉搜索树

cpp 复制代码
/**
 * 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:
    vector<int>nums;
    vector<int> inorder(TreeNode *root){
        if(root == nullptr){
            return nums;
        }
        inorder(root->left);
        nums.push_back(root->val);
        inorder(root->right);
        return nums;
    }
    bool isValidBST(TreeNode* root) {
        vector<int>res;
        res = inorder(root);
        for(int i = 1;i<res.size();i++){
            if(res[i]<=res[i-1]){
                return false;
            }
        }
        return true;
    }
};
cpp 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 * };
 */

class Solution {
public:

    // helper函数作用:
    // 判断以root为根节点的树是否满足BST条件
    //
    // lower:当前节点允许的最小值
    // upper:当前节点允许的最大值
    //
    // 当前节点必须满足:
    // lower < root->val < upper
    bool helper(TreeNode* root, long long lower, long long upper) {


        // 1. 递归终止条件
        //
        // 空节点不违反BST规则
        // 所以返回true
        if(root == nullptr){
            return true;
        }


        // 2. 判断当前节点是否合法
        //
        // BST要求:
        // 当前节点必须严格大于lower
        // 且严格小于upper
        //
        // 如果超出范围,说明不是BST
        if(root->val <= lower || root->val >= upper){
            return false;
        }


        // 3. 递归检查左子树
        //
        // 左子树所有节点都必须小于当前节点
        //
        // 所以:
        // 上界变成当前节点值
        //
        // 原范围:
        // (lower, upper)
        //
        // 左子树范围:
        // (lower, root->val)
        bool left = helper(root->left, lower, root->val);



        // 4. 递归检查右子树
        //
        // 右子树所有节点都必须大于当前节点
        //
        // 所以:
        // 下界变成当前节点值
        //
        // 右子树范围:
        // (root->val, upper)
        bool right = helper(root->right, root->val, upper);



        // 5. 左右子树都满足BST条件
        // 当前树才是BST
        return left && right;
    }



    bool isValidBST(TreeNode* root) {

        // 根节点一开始没有限制
        // 所以给一个最大范围
        return helper(root, LONG_MIN, LONG_MAX);
    }
};

递归思路总结

这道题的核心不是比较:

复制代码
root->left < root
root->right > root

因为这样只能判断直接孩子

例如:

复制代码
        5
       / \
      3   8
         /
        4

看起来:

复制代码
4 < 8

好像满足。

但是 45 的右子树中。

BST要求:

复制代码
右子树所有节点 > 5

而:

复制代码
4 < 5

所以错误。


上下界递归的核心

进入每一层递归,都给当前节点一个合法范围。

比如:

复制代码
        8
       / \
      3   10
     /
    1

开始:

复制代码
8的范围:

(-∞, +∞)

检查左孩子3:

因为3在8左边:

复制代码
3必须满足:

-∞ < 3 < 8

所以递归:

复制代码
helper(3, LONG_MIN, 8)

检查1:

因为1在3左边:

范围继续缩小:

复制代码
-∞ < 1 < 3

所以:

复制代码
helper(1, LONG_MIN, 3)

你会发现:

递归过程中,范围越来越严格。


递归模板

以后遇到类似树的递归,可以套:

复制代码
返回值 dfs(节点, 当前限制){

    // 1. 终止条件
    if(节点为空){
        return 初始结果;
    }


    // 2. 当前节点处理


    // 3. 递归处理子树


    // 4. 合并子树结果


    return 结果;
}

这题:

复制代码
dfs(root, lower, upper)

代表:

判断当前节点是否在合法范围内,并继续检查左右子树。


这道题记忆重点

记住三句话:

① BST性质

复制代码
左子树所有节点 < 根节点 < 右子树所有节点

② 递归传递范围

左子树:

复制代码
helper(root->left, lower, root->val)

因为:

复制代码
左边最大不能超过当前节点

右子树:

复制代码
helper(root->right, root->val, upper)

因为:

复制代码
右边最小不能低于当前节点

③ 递归思想

不要想着:

我要把整棵树全部检查完。

而是:

我相信 helper 可以检查好左右子树,我只需要检查当前节点,并把正确范围传下去。

这就是递归在二叉树问题中的核心思想。

相关推荐
老王熬夜敲代码9 小时前
BLAKE3:最快的密码学哈希函数
算法·密码学·哈希算法
hansang_IR9 小时前
【题解】P4460 [CQOI2018] 解锁屏幕
c++·算法
见闻小天地9 小时前
简博斯JG-C系列彩色激光同轴位移计:摄像头模组对位与行程测量的技术价值观察
人工智能·算法
葫三生10 小时前
《论三生原理》神话学构想与“神话历史”理论、《古史中的神话》思路异同?
大数据·人工智能·科技·深度学习·算法
liliangcsdn10 小时前
因子分析指标概念与示例
算法·机器学习
SupL!11 小时前
LoftQ原理
算法
Navigator_Z13 小时前
LeetCode //C - 1240. Tiling a Rectangle with the Fewest Squares
c语言·算法·leetcode
稻米哟13 小时前
力扣100——双指针
算法·leetcode
明志数科14 小时前
具身智能真机采集工程实践:5类高频失效模式与规避清单
人工智能·算法·机器学习
CSDN_RTKLIB14 小时前
空间哈希与拓扑缓存
算法