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 可以检查好左右子树,我只需要检查当前节点,并把正确范围传下去。

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

相关推荐
不正经学生1 小时前
C语言结构体:自定义数据类型,让变量打包出行
java·c语言·开发语言·数据结构·算法
cxr8282 小时前
数学的本质:关系、模式与不变量的结构世界
人工智能·算法·机器学习
初夏睡觉3 小时前
原创题目 - 空壳恋爱
c++·算法·dp·oi·信息学·原创题目·值得挑战的题目
Buke..3 小时前
【APP 逆向】哔哩哔哩 sign 参数逆向(下):OLLVM 混淆还原 sign 算法
java·javascript·爬虫·python·算法
linux-hzh3 小时前
百日算法修炼 · Day 15
java·算法
闲研随记4 小时前
【文献阅读 ICLR 2026】RL算法:DECS
算法·llm·强化学习·iclr·rl
量化小c4 小时前
一行代码查 BTCUSDT 和 AAPL 最新价?QuantDash 统一多市场实时行情接口实战
后端·算法·github
机器人梦想家4 小时前
具身机器人视觉服务的异步回调与并发控制
数据库·算法·机器人
我命由我123455 小时前
人脸识别 - 人脸识别选帧
java·人工智能·python·算法·安全·java-ee·人脸识别