当前位置: 首页 > news >正文

LeetCode题练习与总结:窥视迭代器--284

一、题目描述

请你在设计一个迭代器,在集成现有迭代器拥有的 hasNext 和 next 操作的基础上,还额外支持 peek 操作。

实现 PeekingIterator 类:

  • PeekingIterator(Iterator<int> nums) 使用指定整数迭代器 nums 初始化迭代器。
  • int next() 返回数组中的下一个元素,并将指针移动到下个元素处。
  • bool hasNext() 如果数组中存在下一个元素,返回 true ;否则,返回 false 。
  • int peek() 返回数组中的下一个元素,但  移动指针。

注意:每种语言可能有不同的构造函数和迭代器 Iterator,但均支持 int next() 和 boolean hasNext() 函数。

示例 1:

输入:
["PeekingIterator", "next", "peek", "next", "next", "hasNext"]
[[[1, 2, 3]], [], [], [], [], []]
输出:
[null, 1, 2, 2, 3, false]解释:
PeekingIterator peekingIterator = new PeekingIterator([1, 2, 3]); // [1,2,3]
peekingIterator.next();    // 返回 1 ,指针移动到下一个元素 [1,2,3]
peekingIterator.peek();    // 返回 2 ,指针未发生移动 [1,2,3]
peekingIterator.next();    // 返回 2 ,指针移动到下一个元素 [1,2,3]
peekingIterator.next();    // 返回 3 ,指针移动到下一个元素 [1,2,3]
peekingIterator.hasNext(); // 返回 False

提示:

  • 1 <= nums.length <= 1000
  • 1 <= nums[i] <= 1000
  • 对 next 和 peek 的调用均有效
  • nexthasNext 和 peek 最多调用  1000 次

二、解题思路

为了实现PeekingIterator类,我们需要在内部维护一个迭代器的状态,并在每次调用nextpeek时更新这个状态。以下是具体的实现步骤:

  1. 在构造函数中,我们需要接收一个整数迭代器nums,并初始化内部状态。我们可以定义一个变量nextElement来存储下一个元素,并在构造函数中立即调用一次next()来填充这个变量。

  2. 实现peek()方法时,我们只需要返回nextElement,而不需要更新迭代器的状态。

  3. 实现next()方法时,我们需要返回nextElement,并在返回之前调用迭代器的next()方法来更新nextElement

  4. 实现hasNext()方法时,我们只需要检查nextElement是否为null,如果是null,则说明没有下一个元素了。

三、具体代码

class PeekingIterator implements Iterator<Integer> {private Integer nextElement = null;private Iterator<Integer> iterator;public PeekingIterator(Iterator<Integer> iterator) {// Initialize any member here.this.iterator = iterator;if (this.iterator.hasNext()) {nextElement = this.iterator.next();}}// Returns the next element in the iteration without advancing the iterator.public Integer peek() {return nextElement;}// hasNext() and next() should behave the same as in the Iterator interface.// Override them if needed.@Overridepublic Integer next() {Integer current = nextElement;nextElement = iterator.hasNext() ? iterator.next() : null;return current;}@Overridepublic boolean hasNext() {return nextElement != null;}
}

四、时间复杂度和空间复杂度

1. 时间复杂度
  • PeekingIterator(Iterator<Integer> iterator):构造函数中调用了hasNext()next()方法,这两个操作的时间复杂度都是O(1),因此构造函数的时间复杂度是O(1)。

  • peek():该方法直接返回nextElement变量,不涉及任何循环或递归调用,因此时间复杂度是O(1)。

  • next():该方法首先保存nextElement的值,然后检查迭代器是否有下一个元素,如果有,则调用next()方法。由于每次调用next()时,迭代器都会移动到下一个元素,这个操作的时间复杂度是O(1)。因此,next()方法的时间复杂度也是O(1)。

  • hasNext():该方法检查nextElement是否为null,这是一个直接的变量访问操作,时间复杂度是O(1)。

综上所述,PeekingIterator类中所有方法的时间复杂度都是O(1)。

2. 空间复杂度
  • PeekingIterator(Iterator<Integer> iterator):构造函数中,我们声明了一个nextElement变量和一个iterator变量。这两个变量的大小不依赖于输入数据的大小,因此空间复杂度是O(1)。

  • peek():该方法没有使用额外的空间,所以空间复杂度是O(1)。

  • next():该方法在执行过程中没有使用额外的空间,除了更新nextElement,所以空间复杂度是O(1)。

  • hasNext():该方法没有使用额外的空间,所以空间复杂度是O(1)。

因此,PeekingIterator类的空间复杂度也是O(1),即常数空间复杂度。这意味着无论输入数据的大小如何,PeekingIterator类使用的空间量保持不变。

五、总结知识点

  • 接口实现(Interface Implementation)

    • PeekingIterator类实现了Iterator<Integer>接口,这意味着它必须提供next()hasNext(), 和remove()方法(尽管在这个类中,remove()方法没有被重写)。
  • 成员变量(Member Variables)

    • nextElement:一个Integer类型的成员变量,用于存储下一次调用next()时将返回的元素。
    • iterator:一个Iterator<Integer>类型的成员变量,用于存储传入的迭代器实例。
  • 构造函数(Constructor)

    • 构造函数接收一个Iterator<Integer>类型的参数,并在内部初始化成员变量。
  • 方法重写(Method Overriding)

    • next():重写了Iterator接口中的next()方法。
    • hasNext():重写了Iterator接口中的hasNext()方法。
  • 条件判断(Conditional Statements)

    • 在构造函数和next()方法中使用了if语句来判断迭代器是否有下一个元素。
  • 三目运算符(Ternary Operator)

    • next()方法中使用三目运算符来简洁地决定nextElement的值。
  • 方法调用(Method Calls)

    • 调用传入迭代器的hasNext()next()方法。
  • 封装(Encapsulation)

    • nextElement被封装在类内部,外部无法直接访问,只能通过peek()方法来查看下一个元素。
  • 返回值(Return Values)

    • peek()方法返回nextElement,但不修改它。
    • next()方法返回nextElement,并更新nextElement为迭代器的下一个元素。
    • hasNext()方法返回一个布尔值,表示是否还有更多的元素。
  • 异常处理(Exception Handling)

    • 虽然在这个类中没有显式地处理异常,但实现迭代器时应该考虑可能抛出的NoSuchElementException(当没有更多元素时调用next())。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。


http://www.mrgr.cn/news/45222.html

相关文章:

  • Docker:容器化技术的革命力量
  • 【Docker从入门到进阶】01.介绍 02.基础使用
  • 大数据毕业设计选题推荐-白酒销售数据分析-Python数据可视化-Hive-Hadoop-Spark
  • <<迷雾>> 第10章 用机器做一连串的加法(1)--使用两排开关分别给出被加数和加数 示例电路
  • C++重载(Overloading)、重写(Overriding)、重定义(Hiding)的对比与区别
  • 14_Linux中参数和变量查看方法
  • 【汇编语言】寄存器(CPU工作原理)(四)—— “段地址x16 + 偏移地址 = 物理地址”的本质含义以及段的概念和小结
  • Android Studio Ladybug | 2024.2.1 更新,快来看看吧
  • 【Linux报错】“-bash: cd: too many arguments“
  • 每日新闻掌握【2024年9月25日 星期三】
  • 数据结构--堆的深度解析
  • 8-传感器和数据
  • 按图搜索1688商品(拍立淘) :API接口编程
  • 【qt】QQ仿真项目2
  • 记一次升级系统补丁导致 VS2022 崩溃分析
  • html+css+js实现轮播图
  • 获取淘宝直播间弹幕数据的技术探索实践方法
  • 面试字节跳动精选20道产品经理面试题分析回答
  • 【数据库】 MongoDB 撤销用户的角色和权限
  • Windows下的python安装教程_2024年10月最新最详细的安装指南