当前位置: 首页 > article >正文

判断二叉搜索树(递归)

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。binary search tree (BST)

有效 二叉搜索树定义如下:

  • 节点的左子树只包含 小于 当前节点的数。
  • 节点的右子树只包含 大于 当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

示例 1:

输入:root = [2,1,3]
输出:true

示例 2:

输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。

提示:

  • 树中节点数目范围在[1, 104] 内
  • -231 <= Node.val <= 231 - 1

中序遍历:

/**
 * 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 {
    long long pre = LLONG_MIN; // 使用 long long 避免溢出
public:
   bool isValidBST(TreeNode* root) {
        if (!root) {
            return true;
        }
        if (!isValidBST(root->left) || root->val <= pre) {
            return false;
        }
        pre = root->val;  // 更新当前节点值
        return isValidBST(root->right);
    }
};

二叉搜索树进行中序遍历,得到的节点值应该是一个严格递增的序列。这意味着,只有当树是有效的二叉搜索树时,按中序遍历得到的值才会从小到大排列。

!isValidBST(root->left) : 

递归检查左子树,如果左子树不是有效的二叉搜索树,返回 false

root->val <= pre:

当前节点值必须大于前一个节点的值

实例:

      5
     / \
    3   7
   / \   / \
  1   4 6   8

第1次递归:根节点 5

  • 当前节点是 5,递归检查左子树。

第2次递归:节点 3

  • 当前节点是 3,递归检查左子树。

第3次递归:节点 1

  • 当前节点是 1,递归检查左子树(为空),返回 true
  • 节点 1 的值比 pre = LLONG_MIN 大,更新 pre = 1
  • 递归检查右子树(为空),返回 true
  • 节点 1 的子树符合 BST 条件,返回 true

回到第2次递归:节点 3

  • 当前节点是 3,递归检查右子树。

第4次递归:节点 4

  • 当前节点是 4,递归检查左子树(为空),返回 true
  • 节点 4 的值比 pre = 1 大,更新 pre = 4
  • 递归检查右子树(为空),返回 true
  • 节点 4 的子树符合 BST 条件,返回 true

回到第2次递归:节点 3

  • 当前节点是 3,递归检查右子树(节点 4),返回 true
  • 节点 3 的值比 pre = 4 小,因此返回 false,树不符合 BST 条件。

后序遍历:

class Solution {
public:
    bool isValidBST(TreeNode* root) {
        return isV(root, LONG_MIN, LONG_MAX);
    }
    
    bool isV(TreeNode* root, long min, long max) {
        if (!root) return true;  // 空节点是有效的
        
        if (root->val <= min || root->val >= max) {
            return false;  // 当前节点值不在有效范围内
        }
        
        return isV(root->left, min, root->val) && 
               isV(root->right, root->val, max);
    }
};

isV(root->left, min, root->val)

对左子树的值进行递归检查,更新右边界为当前节点的值

isV(root->right, root->val, max)

对右子树的值进行递归检查,更新左边界为当前节点的值

实例:

      5
     / \
    3   7
   / \   / \
  1   4 6   8
 

从根节点开始

  • 根节点:值为 5
  • 对于左子树,根节点的值 5 会作为右边界(最大值)。
  • 对于右子树,根节点的值 5 会作为左边界(最小值)。
  • 递归地对左子树和右子树进行检查。

检查左子树

  • 左子树的根节点是 3,并且它的值应该大于 -∞ 并且小于 5
    • 左子树的左节点为 1,它应该大于 -∞ 并且小于 3
    • 左子树的右节点为 4,它应该大于 3 并且小于 5

检查右子树

  • 右子树的根节点是 7,并且它的值应该大于 5 并且小于
    • 右子树的左节点是 6,它应该大于 5 并且小于 7
    • 右子树的右节点是 8,它应该大于 7 并且小于

遍历结束

  • 如果每个节点都符合它应该满足的条件,那么这棵树就是一个有效的二叉搜索树(BST)。
  • 如果有任何节点违反了这个条件,则这棵树不是一个有效的二叉搜索树。


http://www.kler.cn/a/383736.html

相关文章:

  • 网络编程——TCP通信练习
  • 【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
  • OpenAI大事记;GPT到ChatGPT参数量进化
  • Java 中的 transient 关键字:深入解析与实战
  • 【LeetCode】【算法】394. 字符串解码
  • React中类组件和函数组件的理解和区别
  • 【LeetCode】【算法】647. 回文子串
  • 卡码网KamaCoder 127. 骑士的攻击
  • 梧桐数据库之查询特定日期的套餐价格分享
  • (超级详细版)Java基础:Java常用变量详解
  • T507 buildroot linux4.9之MCP2515 can网络开发调试
  • 耕地类项目知识点汇总(持续完善中……)
  • ubuntu22.04安装conda
  • 鸿蒙-promptAction.showToast基于PC屏幕底部提示
  • Ubuntu 安装 RTL8811cu 网卡驱动
  • CTFshow之信息收集第1关到10关。详细讲解
  • SpringBoot基础系列学习(二):配置详解
  • 汉诺塔问题代码分享及思路分享(c基础)
  • Spring Cloud微服务:构建弹性、可扩展的分布式系统
  • AndroidLab:一个系统化的Android代理框架,包含操作环境和可复现的基准测试,支持大型语言模型和多模态模型。
  • Oracle OCP认证考试考点详解082系列15
  • Angular进阶之十:toPromise废弃原因及解决方案
  • 【java】实战-力扣题库:二分查找
  • 首都师范大学地信GIS导师推荐(避坑)
  • 从 vue 源码看问题 — 如何理解 vue 响应式?
  • 【贪心算法】No.1---贪心算法(1)