[LeetCode] Peeking Iterator 頂端迭代器

 

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().html

Example:java

Assume that the iterator is initialized to the beginning of the list: .

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

Hint:git

  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?github

 

這道題讓咱們實現一個頂端迭代器,在普通的迭代器類Iterator的基礎上增長了peek的功能,就是返回查看下一個值的功能,可是不移動指針,next()函數纔會移動指針,那咱們能夠定義一個變量專門來保存下一個值,再用一個bool型變量標記是否保存了下一個值,再調用原來的一些成員函數,就能夠實現這個頂端迭代器了,參見代碼以下:函數

 

解法一:post

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是要暗中觀察一下下一個元素,可是迭代器並不真正移動到下一個,那麼咱們實際上是能夠建立一個副本,而後讓副本移動到下一個,並返回,因爲是局部變量,副本在調用結束後也會被銷燬,因此並無任何內存問題,能夠說是一種至關聰明的解法了,參見代碼以下:this

 

解法二:google

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();
    }
};

 

相似題目:url

Binary Search Tree Iteratorspa

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 題目講解彙總(持續更新中...)

相關文章
相關標籤/搜索