Rearch Interest: Visualization">
284. 窥探迭代器
题目描述
设计一个迭代器,除了支持hasNext和next操作之外,还支持peek操作。
实现PeekingIterator类:
PeekingIterator(int[] nums)使用指定整数数组nums初始化迭代器。int next()返回数组中的下一个元素,并将指针移动到下个元素处。bool hasNext()如果数组中存在下一个元素,返回true;否则,返回false。int peek()返回数组中的下一个元素,但 不 移动指针。
每位数字按照逆序存储,每个节点只能存储一位数字。
示例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 <= 10001 <= nums[i] <= 1000- 对
next和peek的调用均有效 next、hasNext和peek最多调用1000次
进阶:
如何拓展你的设计从而适应所有的类型,而不只是整数型?
方法: 迭代器
最直接的思路: 用一个 列表 存储迭代器中的每个元素, 然后遍历列表模拟迭代器;
更好的方法: 利用 迭代器的性质 实现顶端迭代器的操作。
顶端迭代器需要实现以下三种操作:
next: 返回迭代器的下一个元素、将指针后移一位;hasNext: 判断迭代器中是否还有剩余元素;peek:返回迭代器的下一个元素、不移动指针。
每种编程语言自带的迭代器性质不同,不一定支持上述的所有操作。
以 Java 为例: Iterator
接口支持next和hasNext操作,但是不支持peek
操作。
为了支持peek操作,可以用一个nextElement存储迭代器的下一个元素。
各项操作的具体实现如下:
next: 用表示返回值的ret存储nextElement,然后将nextElement后移一位、返回ret;hasNext: 由于nextElement存储迭代器的下一个元素,因此当nextElement不为空时返回true;peek:由于该操作不移动指针,直接返回nextElement。
时空复杂度: $T(N) = O(1), S(N) = O(1); $
1 | class MySolution2 { |
进阶问题
对于动态语言 (JavaScript, Python等),不需要拓展上述设计。
对于静态语言 (Java, C/C++等),可以使用泛型来扩展设计:
在PeekingIterator中定义泛型,使用时可以用任意类型。
1 | class PeekingIterator<E> implements Iterator<E> { |