Given an Iterator class interface with methods: next() and hasNext(), design and implement a PeekingIterator that support the peek() operation -- it essentially peek() at the element that will be returned by the next call to next().

Example:

Assume that the iterator is initialized to the beginning of the list: [1,2,3].

Call next() gets you 1, the first element in the list.
Now you call peek() and it returns 2, the next element. Calling next() after that still return 2.
You call next() the final time and it returns 3, the last element.
Calling hasNext() after that should return false.

Hint:

  1. Think of "looking ahead". You want to cache the next element.
  2. Is one variable sufficient? Why or why not?
  3. Test your design with call order of peek() before next() vs next() before peek().
  4. For a clean implementation, check out Google's guava library source code.

Follow up: How would you extend your design to be generic and work with all types, not just integer?

这道题让我们实现一个顶端迭代器,在普通的迭代器类Iterator的基础上增加了peek的功能,就是返回查看下一个值的功能,但是不移动指针,next()函数才会移动指针,那我们可以定义一个变量专门来保存下一个值,再用一个bool型变量标记是否保存了下一个值,再调用原来的一些成员函数,就可以实现这个顶端迭代器了,参见代码如下:

解法一:

class Iterator {
struct Data;
Data* data;
public:
Iterator(const vector<int>& nums);
Iterator(const Iterator& iter);
virtual ~Iterator();
// Returns the next element in the iteration.
int next();
// Returns true if the iteration has more elements.
bool hasNext() const;
}; class PeekingIterator : public Iterator {
public:
PeekingIterator(const vector<int>& nums) : Iterator(nums) {
_flag = false;
} int peek() {
if (!_flag) _value = Iterator::next();
_flag = true;
return _value;
} int next() {
if (!_flag) return Iterator::next();
_flag = false;
return _value;
} bool hasNext() const {
return _flag || Iterator::hasNext();
} private:
int _value;
bool _flag;
};

这道题主要的考点就是peek函数,因为这个是默认的迭代器不具备的功能。我们其实可以使用一个小trick来实现peek功能,由于peek是要暗中观察一下下一个元素,但是迭代器并不真正移动到下一个,那么我们其实是可以创建一个副本,然后让副本移动到下一个,并返回,由于是局部变量,副本在调用结束后也会被销毁,所以并没有任何内存问题,可以说是一种相当聪明的解法了,参见代码如下:

解法二:

class Iterator {
struct Data;
Data* data;
public:
Iterator(const vector<int>& nums);
Iterator(const Iterator& iter);
virtual ~Iterator();
// Returns the next element in the iteration.
int next();
// Returns true if the iteration has more elements.
bool hasNext() const;
}; class PeekingIterator : public Iterator {
public:
PeekingIterator(const vector<int>& nums) : Iterator(nums) {} int peek() {
return Iterator(*this).next();
} int next() {
return Iterator::next();
} bool hasNext() const {
return Iterator::hasNext();
}
};

类似题目:

Binary Search Tree Iterator

Flatten 2D Vector

Zigzag Iterator

参考资料:

https://leetcode.com/problems/peeking-iterator/

https://leetcode.com/problems/peeking-iterator/discuss/72650/10-line-C%2B%2B-and-14-line-Java-Implementation

https://leetcode.com/problems/peeking-iterator/discuss/72554/Simple-C%2B%2B-solution-(1-line-per-method)-without-extra-member-variables

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Peeking Iterator 顶端迭代器的更多相关文章

  1. LeetCode Peeking Iterator

    原题链接在这里:https://leetcode.com/problems/peeking-iterator/ 题目: Given an Iterator class interface with m ...

  2. LeetCode——Peeking Iterator

    Description: Given an Iterator class interface with methods: next() and hasNext(), design and implem ...

  3. [Java]LeetCode284. 顶端迭代器 | Peeking Iterator

    Given an Iterator class interface with methods: next() and hasNext(), design and implement a Peeking ...

  4. Leetcode 284.顶端迭代器

    顶端迭代器 给定一个迭代器类的接口,接口包含两个方法: next() 和 hasNext().设计并实现一个支持 peek() 操作的顶端迭代器 -- 其本质就是把原本应由 next() 方法返回的元 ...

  5. Java实现 LeetCode 284 顶端迭代器

    284. 顶端迭代器 给定一个迭代器类的接口,接口包含两个方法: next() 和 hasNext().设计并实现一个支持 peek() 操作的顶端迭代器 – 其本质就是把原本应由 next() 方法 ...

  6. Java之集合初探(二)Iterator(迭代器),collections,打包/解包(装箱拆箱),泛型(Generic),comparable接口

    Iterator(迭代器) 所有实现了Collection接口的容器都有一个iterator方法, 用来返回一个实现了Iterator接口的对象 Iterator对象称作迭代器, 用来方便的实现对容器 ...

  7. Iterator接口(迭代器)

    目录 前言 原理 方法 异常 Iterator接口(迭代器) 前言 一般遍历数组都是采用for循环或者增强for,这两个方法也可以用在集合框架,但是还有一种方法是采用迭代器遍历集合框架,它是一个对象, ...

  8. STL源码分析-iterator(迭代器)

    1. GOF 迭代器设计模式 前面一篇文章有写到stl_list的实现,也实现了一下相应的iterator,但是后面觉得,实现具体容器之前有必要介绍一下iterator(迭代器) .那么迭代器是什么呢 ...

  9. Set,Multiset,Iterator(迭代器)详解

    Set,Multiset,Iterator(迭代器) Iterator:迭代器 我们可以发现所谓一些数据结构比如说数组和链表,它们都有一些相似的性质.我们看下面两个例子: 数组:定义数组\(int~a ...

随机推荐

  1. [JavaEE笔记]Cookie

    引言 由于 Http 是一种无状态的协议,服务器单从网络连接上无从知道客户身份. 会话跟踪是 Web 程序中常用的技术,用来跟踪用户的整个会话.常用会话跟踪技术是 Cookie 与 Session. ...

  2. 工作中遇到的一个多线程下导致RCW无法释放的问题

    最近有个同事在调用一个类库中的方法时遇到了一个问题,异常信息如下: 尝试释放正在使用的RCW,活动线程或其他线程上正在使用该 RCW,释放正在使用的 RCW 的尝试会导致损坏或数据丢失. 该方法中对w ...

  3. Effective前端3:用CSS画一个三角形

    p { text-indent: 2em } .triangle-container p { text-indent: 0 } img { margin: 15px 0 } 三角形的场景很常见,打开一 ...

  4. Spring+SpringMVC+Hibernate简单整合(转)

    SpringMVC又一个漂亮的web框架,他与Struts2并驾齐驱,Struts出世早而占据了一定优势,下面同样做一个简单的应用实例,介绍SpringMVC的基本用法,接下来的博客也将梳理一下Str ...

  5. JAVA大数据数组排序

    对于数据排序大家肯定见过不少,选择排序或者冒泡排序等等,今天我们要做的是快速排序 + 直接插入排序来对大数据(1000万以上)进行排序,下面我们分别来看看这两种排序规则 1, 直接插入排序 (1)基本 ...

  6. Vue基本应用

    1.  returnDetail.$mount('#returnDetail');  不用el 直接可以绑定数据到页面的id上 作用区域不能交叠多个vue 实体 否则后面的vue 实体会失效. 2. ...

  7. Atitit 在线支付系统功能设计原理与解决方案 与目录

    Atitit 在线支付系统功能设计原理与解决方案 与目录 1.1. 支付系统1 1.2. 独立的支付子体系..微服务架构..1 1.3. 参考书籍1 支付战争 [The PayPal Wars:Bat ...

  8. 信息系统实践手记6-JS调用Flex的性能问题一例

    说明:信息系统实践手记系列是系笔者在平时研发中先后遇到的大小的问题,也许朴实和细微,但往往却是经常遇到的问题.笔者对其中比较典型的加以收集,描述,归纳和分享. 摘要:此文描述了笔者接触过的部分信息系统 ...

  9. Graphviz绘制百家争鸣图

    最近读易中天<先秦诸子百家>,一边读一边在纸上画出逻辑关系,图越来越复杂,趁中午休息索性就把图用Graphviz重新绘制了一下;由于Graphviz主动承担了绘图排版的职责,我只需要关注内 ...

  10. DBCC CHECKDB 遭遇Operating system error 112(failed to retrieve text for this error. Reason: 15105) encountered

    我们一个SQL Server服务器在执行YourSQLDBa的作业YourSQLDba_FullBackups_And_Maintenance时遇到了错误: Exec YourSQLDba.Maint ...