【leetcode】98.验证二叉搜索树

文章目录


碎碎念

好!好久没刷leetcode了,欠了好多个题解没给自己补上我有罪...以至于现在好多都忘记了当时怎么做的以及有啥问题...我接下来一定及时写啊啊啊啊!

好累好累啊啊啊最近!忙完你的忙你的忙完你的忙你的...看的眼睛酸酸累累的。不管了,既然这篇开坑了就写完它!


一、题目


二、思路和题解

1.思路

难死我了呃呃呃呃呃

做二叉树相关的题目第一反应还是递归了,但由于苯人对二叉搜索树(BST,Binary Search Tree)的概念还是把握的不是很清晰啊于是只考虑一层的:左节点值小于根节点值,右节点值大于根节点值。一旦出现错的就返回false,没有就继续递归左子树和右子树,直到找到最后都没有false就可以返回true了。

但是!!二叉搜索树不是这样的!二叉搜索树要求左子树的所有节点的值都要小于根节点的值,右子树的所有节点的值也要大于根节点的值。所!以!咱们需要用新的min_nodemax_node变量来存储当前的上界和下界(所以就要引入辅助函数啦),也就是这个节点在什么样一个范围里才是合法的,如果不在这个范围,那就直接false。

举个合法的二叉搜索树的例子,这里我按照层序来一个个讲:

text 复制代码
        5        (根节点)
       / \
      3   7      (3是左子树,7是右子树)
     / \ / \
    2  4 6  8    (叶子节点)
  • 最开始的时候根节点的取值是没有限制的,因此它没有上界和下界;
  • 到3这个节点时,按BST的规则,这个节点必须小于父节点的值,所以上界是5,下界依旧没有;
  • 到7这个节点时,按BST的规则,这个节点必须大于父节点的值,所以下界是5,上界依旧没有;
  • 再往下,到2这个节点时,上界是3,下界没有;
  • 到4这个节点就要注意了,它在3的右子树,所以下界是3,但它同时也在5的左子树,所以上界是5
  • 到6节点,一样的,它在7的左子树,所以上界是7,同时它也在5的右子树,所以下界是5
  • 8这个节点在7的右子树,也在5的右子树,所以下界是5和7,取大的,下界是7。

很显然的,每个节点的值都是在合法的范围的,因此这就是一个合法的BST。

这里的上下界我们手工是看的明白的,但在代码里,就需要"继承"一下啦,我们直接看代码!(建议跟着代码走一遍~)

2.代码(递归)

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:
    // 辅助函数,可以"继承"上下界的值,也可以判断是否在范围内
    bool checkBST(TreeNode* root, TreeNode* min_node, TreeNode* max_node){
    	// 边界条件
        if (root==nullptr){
            return true;
        }
        // 如果超出下界,不合法
        if (min_node!=nullptr&&root->val<=min_node->val){
            return false;
        }
        // 如果超出上界,不合法
        if (max_node!=nullptr&&root->val>=max_node->val){
            return false;
        }
        // 需要接收递归传回来的值,然后查看左右子树是否都合法
        // 注意这里左节点的下界是继承的,上界更新;右节点的上界是继承的,下界更新
        return
        checkBST(root->left,min_node,root)&&checkBST(root->right,root,max_node);
    }
    bool isValidBST(TreeNode* root) {
    	// 初始状态上界和下界都是null
        return checkBST(root,nullptr,nullptr);
    }
};

三、其他解法(中序遍历+判断升序)

1.思路

BST的特点是中序遍历的话是升序的!!

利用这个特点就可以美美解决了,只要不是升序的就是false。

中序遍历请看:【leetcode】94.二叉树的中序遍历(含前序、后序遍历相关内容)

这里我就用的栈模拟了。

2.代码

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:
    // 中序遍历+升序判断
    bool isValidBST(TreeNode* root) {
        vector<int> res;      // 存储遍历结果
        stack<TreeNode*> st;  // 辅助栈
        TreeNode* cur = root; // 游标指针,从根节点开始

        // 循环条件:cur非空或栈非空(两者都空说明遍历完成)
        while (cur != nullptr || !st.empty()) {
            // 把当前节点的所有左孩子依次入栈
            if (cur != nullptr) {
                st.push(cur);
                cur = cur->left;
            } else {
                // 栈顶出栈,访问根节点(加入结果)
                cur = st.top();
                st.pop();
                res.push_back(cur->val);
                // 处理右子树,游标指向右孩子
                cur = cur->right;
            }
        }
		//判断是否升序
        for (int i = 0; i < res.size() - 1; i++) {
            if (res[i] >= res[i + 1]) {
                return false;
            }
        }
        return true;
    }
};

四、错误回顾

1.对BST概念和特点不熟悉,思路上有漏洞,只考虑了一层

2.树的一些基本语法也是手太生了哈,居然都写成root->left.val了...(正确是root->left->val!!!)

相关推荐
黎阳之光18 分钟前
黎阳之光透明管理:视频孪生重构智慧仓储新范式
人工智能·算法·安全·重构·数字孪生
6Hzlia34 分钟前
【Hot 100 刷题计划】 LeetCode 199. 二叉树的右视图 | C++ DFS 逆序遍历
c++·leetcode·深度优先
CappuccinoRose1 小时前
回溯法 - 软考备战(四十三)
算法·排列组合·路径·n皇后·子集·解数独·岛屿
AC赳赳老秦1 小时前
OpenClaw进阶技巧:批量修改文件内容、替换关键词,解放双手
java·linux·人工智能·python·算法·测试用例·openclaw
Robot_Nav2 小时前
Shape-Aware MPPI(SA MPPI)算法:基于RC-ESDF的任意形状机器人实时轨迹优化
算法·机器人·sa-mppi
踩坑记录3 小时前
leetcode hot100 118. 杨辉三角 easy 动态规划
leetcode·动态规划
小O的算法实验室3 小时前
2026年ESWA,自适应基于排序的协同进化学习粒子群算法+边缘计算服务器部署,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
cpp_25013 小时前
P1832 A+B Problem(再升级)
数据结构·c++·算法·动态规划·题解·洛谷·背包dp
꧁细听勿语情꧂4 小时前
合并两个有序表、判断链表的回文结构、相交链表、环的链表一和二
c语言·开发语言·数据结构·算法
木井巳4 小时前
【递归算法】解数独
java·算法·leetcode·决策树·深度优先·剪枝