【面试经典 150 | 二叉树】二叉搜索树迭代器

ops/2025/1/12 23:35:56/

文章目录

  • 写在前面
  • Tag
  • 题目来源
  • 解题思路
    • 方法一:中序遍历到数组
    • 方法二:迭代
  • 写在最后

写在前面

本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更……

专栏内容以分析题目为主,并附带一些对于本题涉及到的数据结构等内容进行回顾与总结,文章结构大致如下,部分内容会有增删:

  • Tag:介绍本题牵涉到的知识点、数据结构;
  • 题目来源:贴上题目的链接,方便大家查找题目并完成练习;
  • 题目解读:复述题目(确保自己真的理解题目意思),并强调一些题目重点信息;
  • 解题思路:介绍一些解题思路,每种解题思路包括思路讲解、实现代码以及复杂度分析;
  • 知识回忆:针对今天介绍的题目中的重点内容、数据结构进行回顾总结。

Tag

二叉搜索树】【递归】【迭代


题目来源

173. 二叉搜索树迭代


解题思路

方法一:中序遍历到数组

思路

设计类,主要两个功能:

  • 一是返回迭代器指针指向当前二叉搜索树中最小节点值;
  • 二是返回迭代器指针当前是否有右侧节点值。

我们知道对于二叉搜索树的中序遍历结果是一个递增的子序列,于是可以利用数组 arr 将其保存。用一个指针 idx (实际上是一个索引)指向数组中元素,调用 next 函数,实际上需要返回的是 arr[i],记得此时需要更新指针的值,为下一次的调用做准备。

调用 hasNext 函数实际上就是在判断 idx 是否已经超越了 arr 的界限,如果没有则返回 true,否则返回 false

初始化的工作就需要将二叉搜索树的中序遍历序列化。

代码

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class BSTIterator {
private:void inorder(TreeNode* root, vector<int>& res) {if (!root) {return;}inorder(root->left, res);res.push_back(root->val);inorder(root->right, res);}vector<int> returnInorderRes(TreeNode* root) {vector<int> res;inorder(root, res);return res;}vector<int> arr;int idx;
public:BSTIterator(TreeNode* root): idx(0), arr(returnInorderRes(root)) {}int next() {return arr[idx++];}bool hasNext() {return idx < arr.size();}
};/*** Your BSTIterator object will be instantiated and called as such:* BSTIterator* obj = new BSTIterator(root);* int param_1 = obj->next();* bool param_2 = obj->hasNext();*/

复杂度分析

时间复杂度:初始化需要时间 O ( n ) O(n) O(n) n n n二叉搜索树中节点的数量。两个成员函数的时间复杂度均为 O ( 1 ) O(1) O(1)

空间复杂度: O ( n ) O(n) O(n)

方法二:迭代

中序遍历可以用递归还实现,也可以使用迭代来实现。利用迭代实现需要借助栈,利用迭代就不需要先将节点值存储下来,可以一般存储一边实现几个成员函数。

代码

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class BSTIterator {
private:TreeNode* cur;stack<TreeNode*> stk;
public:BSTIterator(TreeNode* root): cur(root) {}int next() {while (cur) {stk.push(cur);cur = cur->left;}cur = stk.top(); stk.pop();int res = cur->val;cur = cur->right;return res;}bool hasNext() {return cur != nullptr || !stk.empty();}
};/*** Your BSTIterator object will be instantiated and called as such:* BSTIterator* obj = new BSTIterator(root);* int param_1 = obj->next();* bool param_2 = obj->hasNext();*/

复杂度分析

时间复杂度:初始化和调用 hasNext 都需要时间 O ( 1 ) O(1) O(1)。每次调用 next 最坏需要 O ( n ) O(n) O(n) 时间, n n n二叉搜索树中节点的数量。但考虑到 n n n 次调用 next() \text{next()} next() 函数总共会遍历全部的 n n n 个节点,因此总的时间复杂度为 O ( n ) O(n) O(n),因此单次调用平均下来的均摊复杂度为 O ( 1 ) O(1) O(1)

空间复杂度: O ( n ) O(n) O(n)。最坏情况下二叉搜索树会退化成一条链。


写在最后

如果您发现文章有任何错误或者对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。

如果大家有更优的时间、空间复杂度的方法,欢迎评论区交流。

最后,感谢您的阅读,如果有所收获的话可以给我点一个 👍 哦。


http://www.ppmy.cn/ops/20578.html

相关文章

python递归删除空文件夹

python递归删除空文件夹 作用效果代码 作用 检查指定目录下的所有文件夹是否为空&#xff0c;如果是空则删除。包括子文件夹谨慎选择C盘根目录来测试。 效果 代码 import osdef remove_empty_directories(path):for root, dirs, files in os.walk(path, topdownFalse):for d…

max各种相机导出到ue4匹配镜头的工具集

总览 rollout export_UE4Cam_v2 "导出UE4Cam_v2:半自动" width:200 height:120(HyperLink explain "在打开的max文件中使用" pos:[25,12] width:200 height:15 color:(color 255 155 0) GroupBox grp1 "要导出的相机名" pos:[5,28] width:179 …

Flutter Console运行命令报错解决

通过将包下载到本地点击打开发生闪退 通过clone远程仓库到本地后问题得到解决 git clone -b master https://github.com/flutter/flutter.git ./flutter/bin/flutter --version

【树莓派】常用操作笔记

目录 首次烧录进入ssh功能第一次使用进入root用户增加用户 首次烧录进入ssh功能 首先在SD卡根目录建立一个空的ssh文件(无后缀名)&#xff0c;打开ssh功能。 第一次使用进入root用户 使用pi账户进行登陆命令行&#xff0c;执行命令如下 sudo passwd root #设置root用户密…

Java读取网址信息

Java读取网址信息 今天的需求是根据接口获取JSON数据并存入&#xff0c;之前只会前端用Ajax或者Axios去处理显示出来没想过后端也要拿&#xff0c;没有思路于是查找&#xff0c;发现都是基础以前用的还是太少了&#xff0c;特此总结&#xff0c;后续有需要再补充。 1.读取get请…

npm详解:Node.js的包管理器

npm&#xff08;Node Package Manager&#xff09;是Node.js的包管理器&#xff0c;它允许您安装、更新、删除和发布Node.js软件包。npm是Node.js生态系统中非常重要的组成部分&#xff0c;它使得开发人员能够轻松共享和重用代码&#xff0c;从而提高了开发效率和代码质量。 在…

关于springboot内置tomcat最大请求数配置的一些问题

前言 springboot内置了tomcat。那么一个springboot web应用&#xff0c;最大的请求链接数是多少呢&#xff1f;很早以前就知道这个是有个配置&#xff0c;需要的时候&#xff0c;百度一下即可。但&#xff0c;事实并非如此&#xff0c;有几个问题我想大多数人还真不知道。比如…

SpringBoot 常用注解总结超详细(面试)

目录 一、组件相关&#x1f381; Controller Service Repository Component 二、依赖注入相关&#x1f349; Autowired Resource 根据类型注入&#xff08;By Type&#xff09; 根据名称注入&#xff08;By Name&#xff09; 区别 Qualifier Resource 和 Qualifie…