【力扣题解】P98-验证二叉搜索树-Java题解

2024-01-01 13:20

本文主要是介绍【力扣题解】P98-验证二叉搜索树-Java题解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

花无缺

👨‍💻博客主页:@花无缺
欢迎 点赞👍 收藏⭐ 留言📝 加关注✅!
本文由 花无缺 原创

收录于专栏 【力扣题解】


文章目录

  • 【力扣题解】P98-验证二叉搜索树-Java题解
    • 🌏题目描述
    • 💡题解
    • 🌏总结


【力扣题解】P98-验证二叉搜索树-Java题解

P98.验证二叉搜索树

🌏题目描述

给你一个二叉树的根节点 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

💡题解

递归法1

// list 保存中序序列
List<Long> list = new ArrayList<>();
public boolean isValidBST(TreeNode root) {// 中序遍历二叉树, 将中序序列保存到 list 中dfs(root);// 遍历 list, 如果 list 是一个递增的序列, 那么这就是一棵二叉搜索树for (int i = 0; i < list.size() - 1; i++) {if (list.get(i) >= list.get(i + 1)) {return false;}}return true;
}
public void dfs(TreeNode root) {if (root == null) {return;}dfs(root.left);// 中序遍历, 将节点值放入 listlist.add((long) root.val);dfs(root.right);
}

递归法2

// pre 保存上一个遍历的节点值
long pre = Long.MIN_VALUE;
public boolean isValidBST2(TreeNode root) {// 空树也是二叉搜索树if (root == null) {return true;}// 递归判断左子树boolean left = isValidBST2(root.left);// 如果当前节点的值大于上一个遍历的节点值那么就是符合二叉搜索树的// 继续遍历if (root.val > pre) {pre = root.val;//     如果当前节点的值小于等于上一个遍历的节点值, 那么该树就不是二叉搜索树} else {return false;}// 递归判断右子树boolean right = isValidBST2(root.right);// 左右子树都是二叉搜索树return left && right;
}

时间复杂度均为O(n),需要遍历二叉树的所有节点,二叉树节点数为 n。

🌏总结

我们知道二叉搜索树的左子树的所有节点值一定小于根节点,右子树的所有节点值一定大于根节点,并且所有子树都是二叉搜索树,根据二叉树的这个特性,我们可以推出,二叉搜索树的中序序列一定是一个由小到大排列的递增序列,所以我们可以对树进行中序遍历,然后判断这个序列是否是严格递增的,如果是那么就是二叉搜索树,如果不是那么就不是二叉搜索树。

递归1解法就是采用这个思路的,将中序遍历序列放入列表 list 中,然后判断 list 是否递增。而递归2解法可以不使用列表,而是直接在递归的时候判断当前节点是否大于上一个遍历过的节点,如果递归结束所有节点都满足那么就是二叉搜索树,只要有一个节点是小于等于上一个节点的,那么就不是二叉搜索树。另外,要注意 pre 的初始值要比 int 的最小值小,因为题目的节点值数据范围是整个 int 范围,所以我们直接将 pre 设置为 long 类型数据,并初始化为 long 的最小值。

作者:花无缺(huawuque404.com)


🌸欢迎关注我的博客:花无缺-每一个不曾起舞的日子都是对生命的辜负~
🍻一起进步-刷题专栏:【力扣题解】
🥇往期精彩好文:
📢【全网最全爱心代码仓库】
📢【CSS选择器全解指南】
📢【HTML万字详解】
你们的点赞👍 收藏⭐ 留言📝 关注✅
是我持续创作,输出优质内容的最大动力!
谢谢!

这篇关于【力扣题解】P98-验证二叉搜索树-Java题解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/559377

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

hdu1240、hdu1253(三维搜索题)

1、从后往前输入,(x,y,z); 2、从下往上输入,(y , z, x); 3、从左往右输入,(z,x,y); hdu1240代码如下: #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#inc