98. 验证二叉搜索树

知识点:二叉树;递归

题目描述

给定一个二叉树,判断其是否是一个有效的二叉搜索树。

假设一个二叉搜索树具有如下特征:

节点的左子树只包含小于当前节点的数。

节点的右子树只包含大于当前节点的数。

所有左子树和右子树自身必须也是二叉搜索树。

示例
输入:
2
/ \
1 3
输出: true 输入:
5
/ \
1 4
  / \
  3 6
输出: false
解释: 输入为: [5,1,4,null,null,3,6]。
  根节点的值为 5 ,但是其右子节点值为 4 。

解法一:递归

注意二叉搜索树的含义:每个节点的左子树都小于节点值,每个节点的右子树都大于节点值。

注意以下程序是错的:

class Solution {
public boolean isValidBST(TreeNode root) {
if(root == null) return true;
if(root.left.val > root.val) return false;
if(root.right.val < root.val) return false;
return isValidBST(root.left) && isValidBST(root.right);
}
}

上面程序只检验了每个树的左节点是否小于节点,右节点是否小于节点,比如示例2.不是二叉搜索树,但是会返回true。

每个子树都满足,说明中序遍历的结果(左中右)是递增的序列,所以只要判断后一个序列比前一个序列大即可;中序遍历可用递归或迭代法实现。

函数功能:判断是否是二叉搜索树

1.终止条件:root == null, 返回true;

2.该做什么:判断当前节点和前面节点的值的大小,如果比之前的值小了就直接返回false;

3.什么时候做:就是从中序遍历的结果上比较大小的,中序。

/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
long pre = Long.MIN_VALUE; //先定义一个最小值,注意要在方法外,不然每次递归就又重置了。
public boolean isValidBST(TreeNode root) {
if(root == null) return true;
if(!isValidBST(root.left)) return false;
if(root.val <= pre) return false;
pre = root.val; //更新前一个元素的值;
return isValidBST(root.right);
}
}

空间复杂度:O(N):堆栈的支出

解法二:迭代

/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
long pre = Long.MIN_VALUE;
public boolean isValidBST(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
while(!stack.isEmpty() || root != null){
if(root != null){
stack.push(root); //左边界全部入栈;
root = root.left;
}else{
TreeNode top = stack.pop();
if(top.val <= pre){
return false;
}
root = top.right; //来到弹出节点的右节点;
pre = top.val; //更新上个元素的值;
}
}
return true;
}
}

【LeetCode】98. 验证二叉搜索树的更多相关文章

  1. LeetCode 98. 验证二叉搜索树 | Python

    98. 验证二叉搜索树 题目来源:https://leetcode-cn.com/problems/validate-binary-search-tree 题目 给定一个二叉树,判断其是否是一个有效的 ...

  2. Java实现 LeetCode 98 验证二叉搜索树

    98. 验证二叉搜索树 给定一个二叉树,判断其是否是一个有效的二叉搜索树. 假设一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数. 节点的右子树只包含大于当前节点的数. 所有左子树和右 ...

  3. 力扣Leetcode 98. 验证二叉搜索树

    验证二叉搜索树 给定一个二叉树,判断其是否是一个有效的二叉搜索树. 假设一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数. 节点的右子树只包含大于当前节点的数. 所有左子树和右子树自身 ...

  4. LeetCode 98 验证二叉搜索树

    题目: 给定一个二叉树,判断其是否是一个有效的二叉搜索树. 假设一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数. 节点的右子树只包含大于当前节点的数. 所有左子树和右子树自身必须也是 ...

  5. Leetcode 98 验证二叉搜索树 Python实现

    给定一个二叉树,判断其是否是一个有效的二叉搜索树. 假设一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数. 节点的右子树只包含大于当前节点的数. 所有左子树和右子树自身必须也是二叉搜索 ...

  6. LeetCode 98——验证二叉搜索树

    1. 题目 2. 解答 2.1. 方法一 我们初始化根节点的范围为长整形数据的最小最大值 \([LONG\_MIN,LONG\_MAX]\),则其左子节点的取值范围为 \([LONG\_MIN,根节点 ...

  7. LeetCode 98. 验证二叉搜索树(Validate Binary Search Tree)

    题目描述 给定一个二叉树,判断其是否是一个有效的二叉搜索树. 假设一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数. 节点的右子树只包含大于当前节点的数. 所有左子树和右子树自身必须也 ...

  8. LeetCode:验证二叉搜索树【98】

    LeetCode:验证二叉搜索树[98] 题目描述 给定一个二叉树,判断其是否是一个有效的二叉搜索树. 假设一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数. 节点的右子树只包含大于当 ...

  9. 98. 验证二叉搜索树 前序遍历解法以及后续遍历解法(go语言)

    leetcode题目 98. 验证二叉搜索树 前序遍历 最简洁的答案版本,由于先判断的是根节点,所以直接判断当前root的值v,是否满足大于左子树最大,小于右子树最小,然后再遍历左子树,右子树是否是这 ...

随机推荐

  1. 【题解】codeforces 467C George and Job dp

    题目描述 新款手机 iTone6 近期上市,George 很想买一只.不幸地,George 没有足够的钱,所以 George 打算当一名程序猿去打工.现在George遇到了一个问题. 给出一组有 n ...

  2. Spring @Transaction 注解是如何执行事务的?

    前言 相信小伙伴一定用过 @Transaction 注解,那 @Transaction 背后的秘密又知道多少呢? Spring 是如何开启事务的?又是如何进行提交事务和关闭事务的呢? 画图猜测 在开始 ...

  3. 复习Spring第二课--AOP原理及其实现方式

    AOP原理: AOP,面向方面的编程,使用AOP,你可以将处理方面(Aspect)的代码注入主程序,通常主程序的主要目的并不在于处理这些aspect.AOP可以防止代码混乱.AOP的应用范围包括:持久 ...

  4. [.NET Core知识点回顾]-自动内存管理

    自动内存管理是公共语言运行时在托管执行过程中提供的服务之一.公共语言运行时的垃圾回收器为应用程序管理内存 的分配和释放.对开发人员而言,在开发托管应用程序时不必编写执行内存管理任务代码. 分配内存 初 ...

  5. SpringCloud Alibaba实战(8:使用OpenFeign服务调用)

    源码地址:https://gitee.com/fighter3/eshop-project.git 持续更新中-- 在上一个章节,我们已经成功地将服务注册到了Nacos注册中心,实现了服务注册和服务发 ...

  6. 熬夜总结vue3中setUp函数的2个参数详解

    1.setUp函数的第1个参数props setup(props,context){} 第一个参数props: props是一个对象,包含父组件传递给子组件的所有数据. 在子组件中使用props进行接 ...

  7. ES6学习笔记之函数(一)

    1.函数的默认参数 在ES6 之前,我们不能直接为函数的参数指定默认值,只能采用其他方法.如: function show (num, callback){ num = num || 6; callb ...

  8. Vue(11)组件化的基本使用

    前言 有时候有一组html结构的代码,并且这个上面可能还绑定了事件.然后这段代码可能有多个地方都被使用到了,如果都是拷贝来拷贝去,很多代码都是重复的,包括事件部分的代码都是重复的.那么这时候我们就可以 ...

  9. 为了提高开发效率,我实现了 uTools 的超级面板

    前言 为了进一步提高开发工作效率,最近我们基于 electron 开发了一款媲美 uTools 的开源工具箱 rubick.该工具箱不仅仅开源,最重要的是可以使用 uTools 生态内所有开源插件!这 ...

  10. SpringBoot缓存管理(一) 默认缓存管理

    前言 Spring框架支持透明地向应用程序添加缓存对缓存进行管理,其管理缓存的核心是将缓存应用于操作数据的方法(包括增删查改等),从而减少操作数据的执行次数(主要是查询,直接从缓存中读取数据),同时不 ...