【284中等】顶端迭代器(2021.10.5)
1. 问题描述
请你设计一个迭代器,除了支持hasNext
和next
操作之外,还支持peek操作。
实现PeekingIterator
类:
PeekingIterator(int[] nums)
使用指定整数数组nums
初始化迭代器。int next()
返回数组的下一个元素,并将指针移动到下个元素处。bool hasNext()
如果数组存在下一个元素,返回true
;否则,返回false
。int peek()
返回数组中的下一个元素,但不移动指针。
示例:
输入:
["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 <= num[i] <= 1000
- 对
next
和peek
的调用均有效 next
、hasNext
和peek
最多调用1000
次
2. 解题思路
这是一道类的设计问题,目的是了解STL
中一些基本类的实现。
这道题主要考察的应该是处理逻辑层面和物理层面的错位,由于peek()函数需要查看逻辑层面当前元素的下一个元素,因此就不可避免地使物理迭代器的位置始终位于逻辑位置的后一个位置。这样我们就需要额外的变量维护逻辑层面的数据,即,使用nextValue
暂存下一个元素(也可以理解为当前元素)和hasNextFlag
维护逻辑层面是否存在下一个元素的状态。
3. 代码
/*
* Below is the interface for Iterator, which is already defined for you.
* **DO NOT** modify the interface for Iterator.
*
* class Iterator {
* struct Data;
* Data* data;
* public:
* Iterator(const vector<int>& nums);
* Iterator(const Iterator& iter);
*
* // Returns the next element in the iteration.
* int next();
*
* // Returns true if the iteration has more elements.
* bool hasNext() const;
* };
*/
class PeekingIterator : public Iterator {
int current_value;
bool is_end;
public:
PeekingIterator(const vector<int>& nums) : Iterator(nums) {
// Initialize any member here.
// **DO NOT** save a copy of nums and manipulate it directly.
// You should only use the Iterator interface methods.
is_end = false;
if(Iterator :: hasNext() == true){
current_value = Iterator :: next();
} else {
is_end = true;
}
}
// Returns the next element in the iteration without advancing the iterator.
int peek() {
return current_value;
}
// hasNext() and next() should behave the same as in the Iterator interface.
// Override them if needed.
int next() {
int tmp = current_value;
if(Iterator :: hasNext()){
is_end = false;
current_value = Iterator :: next();
} else {
is_end = true;
current_value = -1;
}
return tmp;
}
bool hasNext() const {
return !is_end;
}
};
使用拷贝的解法:
class PeekingIterator : public Iterator {
public:
PeekingIterator(const vector<int>& nums) : Iterator(nums) {
}
int peek() {
auto tmp = *this;
// 注意:这里不能直接使用this.next(),否则会出错,因为Peek()的指针不能后移。
return tmp.next();
}
int next() {
return Iterator::next();
}
bool hasNext() const {
return Iterator::hasNext();
}
};