题目:顶端迭代器
请你设计一个迭代器,除了支持 hasNext 和 next 操作外,还支持 peek 操作。
实现 PeekingIterator 类:
PeekingIterator(int[] nums) 使用指定整数数组 nums 初始化迭代器。int next() 返回数组中的下一个元素,并将指针移动到下个元素处。bool hasNext() 如果数组中存在下一个元素,返回 true ;否则,返回 false 。int peek() 返回数组中的下一个元素,但 不 移动指针。
示例:
1 | 输入: |
提示:
1 <= nums.length <= 10001 <= nums[i] <= 1000对 next 和 peek 的调用均有效next、hasNext 和 peek 最多调用 1000 次
进阶:你将如何拓展你的设计?使之变得通用化,从而适应所有的类型,而不只是整数型?
分析:
顶端迭代器需要实现以下三种操作:
next:返回迭代器的下一个元素,并将指针向后移动一位;
hasNext:判断迭代器中是否还有剩余的元素;
peek:返回迭代器的下一个元素,不改变指针。
每种编程语言自带的迭代器可能支持上述一种或多种操作,但是不一定支持上述全部操作。如果编程语言自带的迭代器本身就支持上述操作,可以直接使用,否则需要自定义实现。
- C++中
PeekingIterator继承父类Iterator,Iterator已经实现方法next和hasNext,在此我们在PeekingIterator中主要实现peek方法即可。我们使用flag标记迭代器是否还有剩余元素,使用nextElement存储迭代器的下一个元素。
next:首先用ret存储nextElement表示返回值,flag保存Iterator调用hasNext方法的返回结果,然后将nextElement向后移动一位,最后返回ret;
hasNext:返回flag;
peek:由于peek操作不改变指针,因此返回nextElement。
- C#的
IEnumerator接口包含属性Current和方法MoveNext(该方法的返回值类型是bool,表示是否成功移动到下一个元素),三种操作都需要自定义实现,需要使用flag存储迭代器是否还有剩余的元素。
next:首先用ret存储iterator.Current表示返回值,然后对iterator调用MoveNext方法使其向后移动一位并将该方法的结果赋值给flag,最后返回ret;
hasNext:返回flag;
peek:由于peek操作不改变指针,因此返回iterator.Current。
题解:
- C++
1 | class PeekingIterator : public Iterator { |
- C#
1 | class PeekingIterator { |
进阶:
进阶问题
进阶问题要求拓展顶端迭代器的设计,使其适用于所有类型,不局限于整数。
对于动态类型语言如 JavaScript 和 Python,不需要拓展上述设计。
对于静态类型语言如 Java、C# 和 C++,可以通过使用泛型的方式拓展设计,在 PeekingIterator 类中定义泛型,使用时可以用任意类型。
总结:
以前习惯将迭代器当作指针来看到,因为感觉上是大同小异,现在加深了对两者区别的理解:迭代器像是有固定方法的指针,不像指针那么随意,更像是名称所展示的那样包含“迭代”的思想