力扣第98题 验证二叉搜索树 c++ 与上一篇文章相似

news/2024/7/20 22:44:51 标签: 数据结构, 算法, leetcode, c++, 深度优先, 二叉树

题目

98. 验证二叉搜索树

中等

相关标签

树  深度优先搜索  二叉搜索树  二叉树

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

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

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

示例 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

思路和解题方法

第一种方法:

  • 首先定义一个辅助函数 traversal,用于实现中序遍历二叉树,并将节点值存储在一个数组 vec 中。
  • 然后,调用 traversal 函数来遍历二叉树并按顺序存储节点值。
  • 最后,检查数组 vec 是否按照升序排列,若是则为合法的二叉搜索树,返回 true;否则返回 false。

第二种方法:

  • 定义一个全局变量 maxVal,初始值设为 LONG_MIN
  • 使用递归函数 isValidBST 对二叉树进行深度优先搜索。
  • 在搜索过程中,先递归遍历左子树,然后判断当前节点的值是否大于 maxVal,若是则更新 maxVal 为当前节点的值,表示已经访问了当前节点,继续遍历右子树。
  • 若出现当前节点的值小于等于 maxVal,则说明不满足二叉搜索树的要求,返回 false。
  • 如果整个搜索过程中没有出现不满足要求的情况,即二叉树是合法的二叉搜索树,返回 true。

第三种方法:

  • 定义一个指针 pre 用于记录前一个访问的节点。
  • 使用递归函数 isValidBST 对二叉树进行中序遍历。
  • 在中序遍历过程中,先递归遍历左子树,然后判断当前节点的值是否大于前一个节点的值,若不满足这个条件则返回 false。
  • 如果整个中序遍历过程中都满足当前节点值大于前一个节点值的条件,则说明二叉树是合法的二叉搜索树,返回 true。

复杂度

        时间复杂度:

                O(n)

时间复杂度:O(n),其中 nnn 为二叉树的节点个数。二叉树的每个节点最多被访问一次,因此时间复杂度为 O(n)。

        空间复杂度

                O(n)

空间复杂度:O(n),其中 nnn 为二叉树的节点个数。栈最多存储 nnn 个节点,因此需要额外的 O(n)的空间。

c++ 代码一

// 中序遍历二叉树,将节点值按顺序存储在vec数组中
void traversal(TreeNode* root) {
    if(root == NULL) return ;
    // 遍历左子树
    traversal(root->left);
    // 将当前节点值加入数组
    vec.push_back(root->val);
    // 遍历右子树
    traversal(root->right);
}

bool isValidBST(TreeNode* root) {
    // 清空数组
    vec.clear();
    // 进行中序遍历
    traversal(root);
    // 检查数组是否按升序排列
    for(int i = 1; i < vec.size(); i++) {
        // 若出现逆序,则不是二叉搜索树
        if(vec[i] <= vec[i-1]) return false;
    }
    // 数组按升序排列,是二叉搜索树
    return true;
}

c++代码二

long long maxVal = LONG_MIN; // 因为后台测试数据中有int最小值

bool isValidBST(TreeNode* root) {
    // 到达叶节点,返回true,表示是一个合法的搜索二叉树
    if(root == NULL) return true;
    
    // 先递归处理左子树
    bool left = isValidBST(root->left);
    
    // 判断当前节点值是否大于maxVal
    if(maxVal < root->val) 
        maxVal = root->val;
    else 
        return false;
    
    // 再递归处理右子树
    bool right = isValidBST(root->right);
    
    // 左右子树都是合法的搜索二叉树,整棵树才是合法的
    return left && right;
}

c++代码三

TreeNode* pre = NULL; // 用来记录前一个节点

bool isValidBST(TreeNode* root) {
    // 到达叶节点,返回true,表示是一个合法的搜索二叉树
    if(root == NULL) return true;
    
    // 先递归处理左子树
    bool left = isValidBST(root->left);
    
    // 判断当前节点的值是否大于等于前一个节点的值
    if(pre != NULL && pre->val >= root->val)
        return false;
    
    // 更新pre指针为当前节点
    pre = root;
    
    // 再递归处理右子树
    bool right = isValidBST(root->right);
    
    // 左右子树都是合法的搜索二叉树,整棵树才是合法的
    return left && right;
}

c++迭代法

class Solution {
public:
    bool isValidBST(TreeNode* root) {
        stack<TreeNode*> st;  // 创建一个栈用于存储节点
        TreeNode* cur = root;  // 初始化当前节点为根节点
        TreeNode* pre = NULL;  // 初始化前一个节点为NULL,用于记录前一个节点的值
        
        while (cur != NULL || !st.empty()) {
            if (cur != NULL) {
                st.push(cur);  // 将当前节点入栈
                cur = cur->left;  // 继续遍历左子树, 左
            } else {
                cur = st.top();  // 弹出栈顶节点作为当前节点, 中
                st.pop();
                
                // 判断当前节点值是否小于等于前一个节点的值,如果是,则不是有效的二叉搜索树
                if (pre != NULL && cur->val <= pre->val)
                    return false;
                
                pre = cur;  // 更新前一个节点为当前节点
                
                cur = cur->right;  // 继续遍历右子树, 右
            }
        }
        
        return true;  // 遍历完整棵树后,没有发现非法节点值,返回true表示是一个有效的二叉搜索树
    }
};

觉得有用的话可以点点赞,支持一下。

如果愿意的话关注一下。会对你有更多的帮助。

每天都会不定时更新哦  >人<  。


http://www.niftyadmin.cn/n/5080896.html

相关文章

#IIC 通信协议

IIC简介 I2C 通讯协议 (Inter &#xff0d; Integrated Circuit) 是由 Phiilps 公司开发的 物理层 它的物理层有如下特点&#xff1a; (1) 它是一个支持设备的总线。“总线”指多个设备共用的信号线。在一个 I2C 通讯总线中&#xff0c;可连接多个 I2C 通讯设备&#xff0c;支…

COCO格式json切分为labelme可识别json

coco数据格式相关内容参考之前博客 切分的关键在于将coco_json中的annotation信息转化为labelme中shape的坐标信息 labelme中shape需要的是多边形的点坐标&#xff0c;存储格式为[[x1,y1], [x2,y2]......] import os import json import pycocotools.mask as mask_utils fr…

HashMap(2)正文源码分析

序、慢慢来才是最快的方法。 1.简介 HashMap的底层结构是基于分离链表发解决散列冲突的动态散列表。 在Java7中使用数组链表&#xff0c;发生散列冲突的键值对会使用头插法添加到单链表中&#xff1b;在Java8中使用数组链表红黑树&#xff0c;发生散列冲突的键值对会用尾插发…

酷开系统 | 酷开科技助推大屏营销价值提升

随着人口红利的不断减退&#xff0c;移动互联网流量逐渐见顶。寻找新的流量洼地已经被越来越多的品牌方提上日程。而OTT正是这样一个为数不多仍在高速增长的媒介&#xff0c;也成为了构建品牌势能、塑造品牌价值的核心媒介之一。 OTT行业发展至今&#xff0c;伴随着消费者内容…

pdf怎么合并在一起?

pdf怎么合并在一起&#xff1f;对于pdf合并这个问题&#xff0c;有的小伙伴想很简单&#xff0c;只需要将文件直接复制再其中的一个后面不就完事了吗。其实不然&#xff0c;因为我们如果要是需要将很多文件进行合并的话&#xff0c;就会产生很多问题的。总之&#xff0c;在现在…

Spring实战 | Spring IOC不能说的秘密?

国庆中秋特辑系列文章&#xff1a; 国庆中秋特辑&#xff08;八&#xff09;Spring Boot项目如何使用JPA 国庆中秋特辑&#xff08;七&#xff09;Java软件工程师常见20道编程面试题 国庆中秋特辑&#xff08;六&#xff09;大学生常见30道宝藏编程面试题 国庆中秋特辑&…

选择适合自身业务的HTTP代理有哪些因素决定?

相信对很多爬虫工作者和数据采集的企业来说&#xff0c;如何选购适合自己业务的HTTP代理是一个特别特别困扰的选题&#xff0c;市面上那么多HTTP代理厂商&#xff0c;好像这家有这些缺点&#xff0c;转头又看到另外一家的缺点&#xff0c;要找一家心仪的仿佛大海捞针。今天我们…

数据挖掘与统计分析——T检验,正态性检验和一致性检验——代码复现

T检验是一种统计测试&#xff0c;用于确定两个样本组的均值是否有统计学上的显著差异。以下是对T检验的详细介绍&#xff1a; 定义&#xff1a; T检验是一种参数检验&#xff0c;它的前提是数据近似于正态分布。它通过计算T统计量&#xff0c;并将其与特定分布&#xff08;T分…