在问 · 算法题解

284. 窥视迭代器

题目描述

已有一个整数迭代器,只提供两个方法:next() 取出下一个元素并前进一步,hasNext() 判断后面是否还有元素。请基于它实现 PeekingIterator 类,额外支持 peek 操作。

构造函数 PeekingIterator(nums):接收这个整数迭代器 nums。

next():取出接下来的那个元素并返回,迭代位置随之前进。hasNext():还剩元素时返回 true,否则返回 false。peek():只查看接下来的那个元素并返回它,迭代位置保持不动。

各语言的迭代器类型和构造写法可能不同,但都至少提供 next() 和 hasNext()。输入由方法名数组和参数数组组成,构造时的参数是迭代器要遍历的数组;输出按顺序给出每次调用的返回值,构造调用记为 null。

示例 1
输入:nums = ["PeekingIterator","next","peek","next","next","hasNext"]
commands = [[[1,2,3]],[],[],[],[],[]]
输出:[null,1,2,2,3,false]

解释:用 [1,2,3] 构造后:next 得到 1;peek 看到 2 但不前进;接着 next 依次得到 2 和 3;此时没有剩余元素,hasNext 返回 false。

数据范围

  • 1 <= nums.length <= 1000
  • 1 <= nums[i] <= 1000
  • 调用 next 和 peek 时一定还有下一个元素。
  • next、hasNext、peek 合计最多调用 1000 次。

进阶:怎样修改设计,让它不只适用于整数,而能用于任意类型的元素?

解题思路

多读一个元素当缓存:构造时就从底层迭代器取出第一个元素放进 top。peek 直接返回 top;next 先记下 top 作为答案,再从底层读下一个元素补进 top(底层读完则置为 None);hasNext 只要判断 top 是否为 None。

为什么正确

任何时刻 top 都等于“调用者下一次 next 应该得到的元素”;top 为 None 当且仅当已经没有元素。

复杂度分析

三个方法都是 O(1) 时间,额外空间 O(1)(只缓存一个元素)。

易错点

不能直接用底层的 hasNext 判断:缓存里还有一个元素时,底层可能已经读完了,所以 hasNext 必须看 top。另外不要用 0 或 -1 当“空”的标记,数据里可能出现这样的值,用 None(或单独的布尔量)更稳妥。

参考代码

Python、Java、C++、Go、JavaScript、TypeScript 六种语言,逻辑一致。

class PeekingIterator:
    def __init__(self, iterator):
        self.it = iterator
        self.top = None
        if self.it.hasNext():
            self.top = self.it.next()

    def peek(self):
        return self.top

    def next(self):
        ans = self.top
        self.top = None
        if self.it.hasNext():
            self.top = self.it.next()
        return ans

    def hasNext(self):
        return self.top is not None

载入编辑器,自己跑一遍 →

设计 专题的其他题目

查看 设计 全部题目 →