【leetcode热题】二叉搜索树迭代器

实现一个二叉搜索树迭代器类BSTIterator ,表示一个按中序遍历二叉搜索树(BST)的迭代器:

  • BSTIterator(TreeNode root) 初始化 BSTIterator 类的一个对象。BST 的根节点 root 会作为构造函数的一部分给出。指针应初始化为一个不存在于 BST 中的数字,且该数字小于 BST 中的任何元素。
  • boolean hasNext() 如果向指针右侧遍历存在数字,则返回 true ;否则返回 false 。
  • int next()将指针向右移动,然后返回指针处的数字。

注意,指针初始化为一个不存在于 BST 中的数字,所以对 next() 的首次调用将返回 BST 中的最小元素。

你可以假设 next() 调用总是有效的,也就是说,当调用 next() 时,BST 的中序遍历中至少存在一个下一个数字。

示例:

输入
["BSTIterator", "next", "next", "hasNext", "next", "hasNext", "next", "hasNext", "next", "hasNext"]
[[[7, 3, 15, null, null, 9, 20]], [], [], [], [], [], [], [], [], []]
输出
[null, 3, 7, true, 9, true, 15, true, 20, false]

解释
BSTIterator bSTIterator = new BSTIterator([7, 3, 15, null, null, 9, 20]);
bSTIterator.next();    // 返回 3
bSTIterator.next();    // 返回 7
bSTIterator.hasNext(); // 返回 True
bSTIterator.next();    // 返回 9
bSTIterator.hasNext(); // 返回 True
bSTIterator.next();    // 返回 15
bSTIterator.hasNext(); // 返回 True
bSTIterator.next();    // 返回 20
bSTIterator.hasNext(); // 返回 False

解法一

先不考虑题目 Note 中要求的空间复杂度和时间复杂度,简单粗暴一些。在构造函数中,对二叉树进行中序遍历,把结果保存到一个队列中,然后 next 方法直接执行出队操作即可。至于 hasNext 方法的话,判断队列是否为空即可。

class BSTIterator {

    Queue<Integer> queue = new LinkedList<>();

    public BSTIterator(TreeNode root) {
        inorderTraversal(root);
    }

    private void inorderTraversal(TreeNode root) {
        if (root == null) {
            return;
        }
        inorderTraversal(root.left);
        queue.offer(root.val);
        inorderTraversal(root.right);
    }

    /** @return the next smallest number */
    public int next() {
        return queue.poll();
    }

    /** @return whether we have a next smallest number */
    public boolean hasNext() {
        return !queue.isEmpty();
    }
}

时间复杂度的话,构造函数因为遍历了一遍二叉树,所以是 O(n),对于 next 和 hasNext 方法都是 O(1)

空间复杂度,用队列保存了所有的节点值,所以是 O(n),此外中序遍历递归压栈的过程也需要 O(h) 的空间。

解法二

解法一中我们把所有节点都保存了起来,其实没必要一次性保存所有节点,而是需要一个输出一个即可。

所以我们要控制中序遍历的进程,不要让它一次性结束,如果用解法一递归的方法去遍历那就很难控制了,所以自然而然的会想到用栈模拟递归的过程。

下边是 94 题 解法二的代码。

public List<Integer> inorderTraversal(TreeNode root) {
    List<Integer> ans = new ArrayList<>();
    Stack<TreeNode> stack = new Stack<>();
    TreeNode cur = root;
    while (cur != null || !stack.isEmpty()) {
        //节点不为空一直压栈
        while (cur != null) {
            stack.push(cur);
            cur = cur.left; //考虑左子树
        }
        //节点为空,就出栈
        cur = stack.pop();
        //当前值加入
        ans.add(cur.val);
        //考虑右子树
        cur = cur.right;
    }
    return ans;
}

和这道题糅合一起也很简单了,只需要把 stack 和 cur 作为成员变量,然后每次调用 next 就执行一次 while 循环,并且要记录当前值,结束掉本次循环。

class BSTIterator {
    Stack<TreeNode> stack = new Stack<>();
    TreeNode cur = null;

    public BSTIterator(TreeNode root) {
        cur = root;
    }

    /** @return the next smallest number */
    public int next() {
        int res = -1;
        while (cur != null || !stack.isEmpty()) {
            // 节点不为空一直压栈
            while (cur != null) {
                stack.push(cur);
                cur = cur.left; // 考虑左子树
            }
            // 节点为空,就出栈
            cur = stack.pop();
            res = cur.val;
            // 考虑右子树
            cur = cur.right;
            break;
        }

        return res;
    }

    /** @return whether we have a next smallest number */
    public boolean hasNext() {
        return cur != null || !stack.isEmpty();
    }
}

时间复杂度的话,对于 next 方法,大多数时候是 O(1),但最坏情况因为最里边的 while 循环,其实有可能达到 O(n)。但如果算均摊时间复杂度的话,其实还是 O(1),因为每个节点最多也就经过两次就出栈了。

空间复杂度,这里只需要消耗栈的空间,也就是 O(h)

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

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

相关文章

微信小程序 canvas层级过高覆盖原生组件

一、背景 微信小程序中使用signature第三方插件完成签名效果&#xff0c;但真机调试时发现canvas层级过高遮挡了按钮 二、具体问题 问题原因&#xff1a;签名后点击按钮无法生效 问题代码&#xff1a; <template><view class"sign_page" v-cloak>&l…

Linux 服务升级:MySQL 主从(半同步复制) 平滑升级

目录 一、实验 1.环境 2.Mysql-shell 检查工具兼容性 3.逻辑备份MySQL数据 4.备份MySQL 数据目录、安装目录、配置文件 5.MySQL 升级 6.master节点 使用systemd管理mysql8 7. slave1 节点升级 8. slave2 节点升级 9.半同步设置 二、问题 1.mysqldump备份报错 2.Inn…

【linux】Debian访问Debian上的共享目录

要在Debian系统上访问共享目录&#xff0c;通常意味着要访问通过网络共享的文件夹&#xff0c;比如通过SMB/CIFS&#xff08;Server Message Block/Common Internet File System&#xff09;协议共享的Windows共享文件夹。以下是访问共享目录的步骤&#xff1a; 1. 安装必要的…

kafka2.x版本配置SSL进行加密和身份验证

背景&#xff1a;找了一圈资料&#xff0c;都是东讲讲西讲讲&#xff0c;最后我还没搞好&#xff0c;最终决定参考官网说明。 官网指导手册地址&#xff1a;Apache Kafka 需要预备的知识&#xff0c;keytool和openssl 关于keytool的参考&#xff1a;keytool的使用-CSDN博客 …

MacOS Xcode 使用LLDB调试Qt的 QString

环境&#xff1a; MacOS&#xff1a; 14.3Xcode&#xff1a; Version 15.0Qt&#xff1a;Qt 6.5.3 前言 Xcode 中显示 预览 QString 特别不方便, 而Qt官方的 lldb 脚本debugger/lldbbridge.py一直加载失败&#xff0c;其他第三方的脚本都 不兼容当前的 环境。所以自己研究写…

使用华为云HECS服务器+nodejs开启web服务

简介: 在华为云HECS服务器上使用nodejs开启一个web服务。 目录 1.开通华为云服务器 2.远程登录 2.1 使用华为官方的网页工具登录 ​编辑 2.2 使用MobaXterm登录 3 安装node 3.1 下载 2. 配置环境变量 4. 安装express模块 5.开启外网访问 1.开通华为云服务器 这…

Flutter-底部弹出框(Widget层级)

需求 支持底部弹出对话框。支持手势滑动关闭。支持在widget中嵌入引用。支持底部弹出框弹出后不影响其他操作。支持弹出框中内容固定头部和下面列表时&#xff0c;支持触摸头部并在列表不在头部的时候支持滑动关闭 简述 通过上面的需求可知&#xff0c;就是在界面中可以支持…

20240319在WIN10下给K6000按照驱动程序

20240319在WIN10下给K6000按照驱动程序 2024/3/19 18:12 http://nvidia.cn/ Skip to main content 驱动程序下载 NVIDIA>驱动下载> NVIDIA RTX / Quadro Desktop and Notebook Driver Release 470 Registration Keynote GTC ˆ›šš‰ˆš Portal Prelude DOCA Early Ac…

MySQL 搭建双主复制服务 并 通过 HAProxy 负载均衡

一、MySQL 搭建双主复制高可用服务 在数据库管理中&#xff0c;数据的备份和同步是至关重要的环节&#xff0c;而双主复制&#xff08;Dual Master Replication&#xff09;作为一种高可用性和数据同步的解决方案&#xff0c;通过让两个数据库实例同时充当主服务器和从服务器&…

Java 设计模式系列:行为型-状态模式

简介 状态模式&#xff08;State Pattern&#xff09;是一种行为型设计模式&#xff0c;允许一个对象在其内部状态改变时改变其行为。状态模式中类的行为是由状态决定的&#xff0c;在不同的状态下有不同的行为。 状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂…

智能合约语言(eDSL)—— 使用rust实现eDSL的原理

为理解rust变成eDSL的实现原理&#xff0c;我们需要简单了解元编程与宏的概念,元编程被描述成一种计算机程序可以将代码看待成数据的能力&#xff0c;使用元编程技术编写的程序能够像普通程序在运行时更新、替换变量那样操作更新、替换代码。宏在 Rust 语言中是一种功能&#x…

鸿蒙开发实战:【系统服务管理部件】

简介 samgr组件是OpenHarmony的核心组件&#xff0c;提供OpenHarmony系统服务启动、注册、查询等功能。 系统架构 图 1 系统服务管理系统架构图 目录 /foundation/systemabilitymgr ├── samgr │ ├── bundle.json # 部件描述及编译文件 │ ├── frameworks …

多特征变量序列预测(11) 基于Pytorch的TCN-GRU预测模型

往期精彩内容&#xff1a; 时序预测&#xff1a;LSTM、ARIMA、Holt-Winters、SARIMA模型的分析与比较-CSDN博客 风速预测&#xff08;一&#xff09;数据集介绍和预处理-CSDN博客 风速预测&#xff08;二&#xff09;基于Pytorch的EMD-LSTM模型-CSDN博客 风速预测&#xff…

基于springboot+vue的智慧生活商城系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

Stability AI 3D:开创3D视觉技术新篇章,提升多视角连贯性与生成质量

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

杰发科技AC7801——Flash数据读取

0. 简介 因为需要对Flash做CRC校验&#xff0c;第一步先把flash数据读出来。 1. 代码 代码如下所示 #include "ac780x_eflash.h" #include "string.h" #define TestSize 1024 ///< 4K #define TestAddressStart 0x08000000 uint8_t Data[7000]; int…

【NLP笔记】Transformer

文章目录 基本架构EmbeddingEncoderself-attentionMulti-Attention残差连接LayerNorm DecoderMask&Cross Attention线性层&softmax损失函数 论文链接&#xff1a; Attention Is All You Need 参考文章&#xff1a; 【NLP】《Attention Is All You Need》的阅读笔记 一…

多数据源 - dynamic-datasource | 集成 HikariCP 连接池

文章目录 连接池集成简介HikariCP 连接池默认 HikariCP 配置自定义 HikariCP 配置Druid 连接池BeeCp 连接池DBCP2 连接池JNDI 数据源🗯️ 上节回顾:上一节中,实现了 dynamic-datasource 的快速入门。 👉 本节目标:在上一节的基础上,集成 HikariCP 数据库连接池并介绍原…

es 集群安全认证

参考文档&#xff1a;Configure security for the Elastic Stack | Elasticsearch Guide [7.17] | Elastic ES敏感信息泄露的原因 Elasticsearch在默认安装后&#xff0c;不提供任何形式的安全防护不合理的配置导致公网可以访问ES集群。比如在elasticsearch.yml文件中,server…

【SpringSecurity】十三、基于Session实现授权认证

文章目录 1、基于session的认证2、Demosession实现认证session实现授权 1、基于session的认证 流程&#xff1a; 用户认证成功后&#xff0c;服务端生成用户数据保存在session中服务端返回给客户端session id (sid&#xff09;&#xff0c;被客户端存到自己的cookie中客户端下…
最新文章