算法题解记录25+++验证二叉搜索树(百日筑基)

题目描述:

        难度:中等

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

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

  • 节点的左

    子树

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

示例 1:

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

示例 2:

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

提示:

  • 树中节点数目范围在[1, 10^4] 内
  • -2^31 <= Node.val <= 2^31 - 1

解题准备:

        1.题意:题目要求验证一棵二叉树,是不是二叉搜索树(BST,即Binary Search Tree),那么我们首先要知道,一棵二叉搜索树是什么样的。

        简单地说,BST有如下性质:第一,其左子树上所有节点的值,都小于根节点值;第二,其右子树上所有节点的值,都大于根节点的值。第三,BST下所有节点,都有BST的性质。

        2.基本操作:就题目看,不涉及增删改,验证必然要涉及查找遍历,姑且认为只有查找和比较。

        3.基础原理:面对树的题目,我们应敏锐地察觉到至少两种方法---BFS广度优先搜索和DFS深度优先搜索。这两种方法几乎是树的算法的基础,大多数算法,都是在二者之上优化而得。

解题思路:

        朴素地说,对于新手,其实一看到这个题目,是不会有什么思路的。

        然而,如果说做过一些题,就能直接得到答案,也非常夸张。

        我在此分享我的错误思路。

        错误思路---左右递归判断

                我最开始的思路比较简单,基于两个基本原理:

                第一,如果一棵树左子节点left的值,大于或等于根节点root的值,说明它不是BST。

                第二,如果一棵树右子节点right的值,小于或等于根节点root的值,说明不是BST。

                这两个原理没有错,却不完全,如果一棵树满足这两个原理,也有可能不是BST,比如下图,7大于5,却满足这个原理,同样,3小于5,也满足这个原理。

                这两个原理没有满足整体,所以我编写的代码在运行之后也报错了,不过,我会在下面提供代码。我先在此说明我的思考过程。【如何将这两个原理转化为代码的】

                第一步,有了原理,尽量往dfs或者bfs方法上靠近。

                第二步,发现判断一个节点是否满足2个原理,只需要判断left与root的关系、right与root的关系即可。【异常处理还没做】

                第三步,得到问题:虽然判断一个节点很简单,怎么判断下一个呢?

                第四步,初始的朴素思想:干脆中序遍历或前序遍历一遍,得到所有节点(存储List),依次进行判断?

                第五步,想到优化思路,既然中序遍历能够遍历每个节点,为什么要遍历一边,然后又从List再遍历一遍?

                第六步,中序原理是左根右,访问操作只在根节点做,那么继续左中右方法,把判断左子放在“左”,判断右子放在“右”,根节点的数据访问忽略了,就可以了。

                第七步,异常:访问到空节点null。

                第八步:if限制,null节点直接返回,又因为要判断子节点与根节点的关系,返回明显不能处理,所以需要额外判断子节点是否为null。

                完成。

        正确思路---中序遍历序列

                这个思路首先要明白一件事:中序遍历,其顺序是左子树、根节点、右子树。

                其中,在左子树left中,其顺序也是left的左子树、left、left的右子树。

                如果一棵树只有一个节点,毫无疑问它是升序的。

                假设这棵树root,它的左子树是left,右子树是right。

                那么,中序遍历时,一定会访问到left的最左子节点X,它是升序的。

                接着,访问最左子节点的父节点F,由于BST性质,最左子X小于F,所以是升序的。

                然后,访问F的右子【也有可能是右子的左子、右子的左子的左子……】P,由于BST性质,XFP升序排列。

                由于这棵树升序排列,那么,它的父树也升序排列,最后,left升序排列,整个节点的中序序列,都升序排列。

                由此,我们只需要得到中序序列,即可判断。

        正确思路---区间逼近

                这个思路是题解的思路,不过与我的错误思路非常接近,它把我的2个原理推进了。

                原理1:左子节点left,一定比root小,左子的左子,一定比root小;左子的右子,一定比root小,并且比左子大……

                原理2:右子节点right,一定比root大,右子的右子,一定比root大;右子的左子,一定比root大,并且比右子小。

                如此,我们可以发现,我的错误思路,就在于判断时,只是把节点与其左右子进行判断,忽略了最重要的根节点。

                然而,问题出现了:如果我们持续用root的值,作为判断依据,如下图:5作为右边所有节点的下限,没有问题,但是9却比7要大,也就是说子树7不符合BST的性质,所以整棵树不是BST。

                换句话说,我们要求上下限是不断变化的,这其实也是二叉树的精髓部分。

                怎么做呢?

                一般的想法是,维护两个变量low、up,使它们代表某个节点的上下限,在每次判断时作为依据。

                不过,如果这两个变量只是代表1个节点上下限,那么我们要开辟一个非常大的空间,用来存储所有的变量对low、up。

                所以,借助递归的方案,我们把维护变量对的操作交给系统,我们只需要递归调用时,传递变量对即可。

解题难点分析:

        无

错误代码---我的思路:

class Solution {
    public boolean isValidBST(TreeNode root) {
        boolean flag = true;
        // 为null不判断
        if(root.left!=null){
            if(root.left.val>=root.val){
                return false;
            }
            flag = isValidBST(root.left);
        }
        // 看一下是否不是BST
        if(!flag){
            return flag;
        }
        // 同理
        if(root.right!=null){
            if(root.right.val<=root.val){
                return false;
            }
            flag = isValidBST(root.right);
        }

        return flag;
    }
}

代码---中序遍历:

class Solution {
    public boolean isValidBST(TreeNode root) {
        // 存储节点
        List<Integer> data = new ArrayList<>();
        fuzhu(root, data);
        // 依次判断
        for(int i=0; i<data.size()-1; i++){
            if(data.get(i) >= data.get(i+1)){
                return false;
            }
        }

        return true;
    }

    private void fuzhu(TreeNode root, List<Integer> data){
        if(root==null){
            return;
        }

        fuzhu(root.left, data);
        data.add(root.val);
        fuzhu(root.right, data);
    }
}

代码---迭代上下限:

class Solution {
    public boolean isValidBST(TreeNode root) {
        return fuzhu(root, Long.MIN_VALUE, Long.MAX_VALUE);
    }

    private boolean fuzhu(TreeNode root, long low, long up){
        // 如果是空节点,即正确 
        if(root==null){
            return true;
        }
        
        // 如果超出界限,则错误
        // 我们可以看出来,每次递归判断,只能判断一个节点,我们不可能一起判断左子和右子
        if(root.val <= low || root.val >= up){
            return false;
        }

        // 返回左子节点、右子节点的判断。
        return fuzhu(root.left, low, root.val) && fuzhu(root.right, root.val, up);
    }
}

以上内容即我想分享的关于力扣热题25的一些知识。

        我是蚊子码农,如有补充,欢迎在评论区留言。个人也是初学者,知识体系可能没有那么完善,希望各位多多指正,谢谢大家。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/621250.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

浅谈现代消息队列与云存储

一、前言 1970 年代末&#xff0c;消息系统用于管理多主机的打印作业&#xff0c;这种削峰解耦的能力逐渐被标准化为“点对点模型”和稍复杂的“发布订阅模型”&#xff0c;实现了数据处理的分布式协同。随着时代的发展&#xff0c;Kafka&#xff0c;Amazon SQS&#xff0c;Ro…

【主题广泛|稳定检索】2024年社会科学、公共服务与人文艺术国际会议(SPSHA 2024)

2024年社会科学、公共服务与人文艺术国际会议&#xff08;SPSHA 2024&#xff09; 2024 International Conference on Social Sciences, Public Services, and Humanities and Arts 【会议简介】 本次会议定于2024年在中国的繁华都市——广州召开&#xff0c;汇聚了全球在该领…

使用Vue3开发项目,搭建Vue cli3项目步骤

1.打开cmd &#xff0c;输入 vue create neoai遇到这样的问题 则需要升级一下电脑上 Vue Cli版本哈 升级完成之后 再次输入命令&#xff0c;创建vue3项目 vue create neoai安装完成后&#xff0c;输入 npm run serve 就可以运行项目啦~ 页面运行效果

C#知识|上位机UI设计-详情窗体设计思路及流程(实例)

哈喽,你好啊,我是雷工! 上两节练习记录了登录窗体和主窗体的实现过程,本节继续练习内容窗体的实现,以下为练习笔记。 01 详情窗体效果展示: 02 添加窗体并设置属性 在之前练习项目的基础上添加一个Windows窗体,设置名称为:FrmIPManage.cs 设置窗体的边框和标题栏的外…

Mask2former代码详解

1.整体流程 Mask2former流程如图所示&#xff0c;对于输入图片&#xff0c;首先经过Resnet等骨干网络获得多层级特征&#xff0c;对于获得的多层级特征&#xff0c;一个方向经过pixel decoder(基于DetrTransformerEncoderLayer)得到per-pixel embedding,另外一个方向经过transf…

【C++初阶】string模拟实现

✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅ ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨ &#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1…

2024年抖店什么类目赚钱?这八个类目最赚钱,想开店的快来瞅瞅!

哈喽~我是电商月月 做抖音小店的商家都知道&#xff0c;选品是非常重要的 那什么样的商品类型赚钱&#xff0c;哪些商品又适合新手操作呢? 今天我就给大家推荐几个热销类目&#xff0c;特别是最后两个&#xff0c;下半年说不定会小爆一把哦 一&#xff0e;日用百货 这个类…

自制无感无刷电机驱动板

自制无感无刷电机驱动板 分别测试了基于C251的STC32G单片机、Arduino AVR的ATmega328PB、以及ARM的ST32F103单片机。 &#x1f9f2;测试转动效果 ✒目前市面上开源的有关无刷电机的项目数不胜数&#xff0c;其控制原理都大同小异&#xff0c;在没有领透其技术要领情况下&#x…

第六节笔记及作业----Lagent AgentLego 智能体应用搭建

关于 Agent 的相关理论 大语言模型存在一些局限性&#xff0c;比如会出现幻觉问题、有时效性问题以及可靠性问题。智能体的定义是具备感知、决策和行动能力的实体。智能体主要由感知部分、大脑部分和动作部分组成。智能体有多种类型&#xff0c;如 ReAct 类型&#xff08;侧重…

5.10.8 Transformer in Transformer

Transformer iN Transformer (TNT)。具体来说&#xff0c;我们将局部补丁&#xff08;例如&#xff0c;1616&#xff09;视为“视觉句子”&#xff0c;并将它们进一步划分为更小的补丁&#xff08;例如&#xff0c;44&#xff09;作为“视觉单词”。每个单词的注意力将与给定视…

智慧党建小程序源码系统 源码全开源支持二次开发 带完整的安装代码包以及搭建部署教程

源码系统概述 智慧党建小程序源码系统是一款基于微信小程序开发的党建管理工具&#xff0c;它集党员管理、党费收缴、活动组织、信息发布等功能于一体&#xff0c;实现了党建工作的全面数字化。该系统采用先进的云计算和大数据技术&#xff0c;支持多平台、多终端访问&#xff…

J-STAGE (日本电子科学与技术信息集成)数据库介绍及文献下载

J-STAGE (日本电子科学与技术信息集成)是日本学术出版物的平台。它由日本科学技术振兴机构&#xff08;JST&#xff09;开发和管理。该系统不仅包括期刊&#xff0c;还有论文集&#xff0c;研究报告、技术报告等。文献多为英文&#xff0c;少数为日文。目前网站上所发布的内容来…

二.基础篇: 面向对象进阶

1. 基础篇语法篇&#xff1a;一.基础篇&#xff1a;基础语法-CSDN博客 面向对象进阶 本章主要学习内容&#xff1a; static继承包&#xff0c;final&#xff0c;权限修饰符&#xff0c;代码块抽象类接口多态内部类 1. static static翻译过来就是静态的意思static表示静态&am…

家用洗地机哪款最好用?附热门洗地机品牌推荐,看完这篇不踩坑

随着技术的不断发展&#xff0c;现在的洗地机功能已经越来越强大了&#xff0c;它可以高效的扫地、拖地、不用手动清洗滚刷&#xff0c;甚至有些中高端型号还能边洗地边除菌&#xff0c;远程操控自清洁&#xff0c;简直就是家居清洁的小能手&#xff01;那么&#xff0c;家用洗…

‘vue-cli-service‘ is not recognized as an internal or external command解决方案

vue-cli-service is not recognized as an internal or external command, operable program or batch file.解决方案 先进行 &#xff1a; npm install -g vue/cli 命令安装vue cli 是必须的。 如果 npm run build 还是报错 遇到同样的提示&#xff1a; 这时候先安装依赖 np…

深入理解与应用C++ Vector

1. C Vector 简介与基本使用 C 的 vector 是一个序列容器&#xff0c;用于表示可变大小的数组。它结合了数组的高效元素访问和动态大小调整的灵活性。与静态数组相比&#xff0c;vector 的大小可以根据需要自动调整&#xff0c;这是通过在底层使用动态数组来实现的。当新元素被…

返回倒数第K个节点(C语言)———链表经典算法题

题目描述​​​​​​&#xff1a;面试题 02.02. 返回倒数第 k 个节点 - 力扣&#xff08;LeetCode&#xff09;&#xff1a; 答案展示: /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/int kthToLast(struct Li…

娱乐营销的新玩法:Kompas.ai如何让内容更加趣味化

在数字化时代&#xff0c;内容营销已成为品牌与消费者沟通的重要桥梁。然而&#xff0c;随着信息的爆炸式增长&#xff0c;用户的注意力越来越分散&#xff0c;传统的营销方式已经难以吸引用户的兴趣。在这种背景下&#xff0c;娱乐营销应运而生&#xff0c;它通过将娱乐元素融…

2023年30米分辨率土地利用遥感监测数据

改革开放以来&#xff0c;中国经济的快速发展对土地利用模式产生了深刻的影响。同时&#xff0c;中国又具有复杂的自然环境背景和广阔的陆地面积&#xff0c;其土地利用变化不仅对国家发展&#xff0c;也对全球环境变化产生了深刻的影响。为了恢复和重建我国土地利用变化的现代…

R语言:GSEA分析

#安装软件包 > if (!requireNamespace("BiocManager", quietly TRUE)) install.packages("BiocManager") > BiocManager::install("limma") > BiocManager::install("org.Hs.eg.db") > BiocManager::install("…