【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!!!)

相关推荐
一叶落4381 小时前
【LeetCode 172】阶乘后的零(C语言详解 | 数学规律 + 对数时间复杂度)
c语言·数据结构·算法·leetcode·动态规划
自信150413057591 小时前
数据结构初阶——二叉树之——堆的实现
c语言·数据结构·算法
!停2 小时前
数据结构算法—归并排序
数据结构·算法
骇客野人2 小时前
机器学习线性回归算法是入门机器学习理解人工智能模型很好示例
人工智能·算法·机器学习
Trouvaille ~2 小时前
【贪心算法】专题(三):排序、博弈与区间的贪婪法则
c++·算法·leetcode·青少年编程·面试·贪心算法·蓝桥杯
Sakinol#2 小时前
Leetcode Hot 100 —— 二叉树 part02
算法·leetcode
N1_WEB2 小时前
HDU:杭电 2017 复试真题汇总
算法
努力学算法的蒟蒻2 小时前
day111(3.13)——leetcode面试经典150
算法·leetcode·面试
参.商.2 小时前
【Day37】94.二叉树的中序遍历 递归+迭代遍历
leetcode·golang