[LeetCode] Peeking Iterator
An interesting problem about iterators. This post shares a very nice solution, which is rewritten below, with minor simplifications.
// 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); 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) { // Initialize any member here. // **DO NOT** save a copy of nums and manipulate it directly. // You should only use the Iterator interface methods. peeked = false; } // Returns the next element in the iteration without advancing the iterator. int peek() { if (!peeked) { peeked = true; peekElem = Iterator::next(); } return peekElem; } // hasNext() and next() should behave the same as in the Iterator interface. // Override them if needed. int next() { if(peeked) { peeked = false; return peekElem; } return Iterator::next(); } bool hasNext() const { return peeked || Iterator::hasNext(); } private: bool peeked; int peekElem; };
BTW, it seems that we tend to misspell peek to peak. Well, after learning what peek
wants to do, I understood why it uses such a name: peek means to look furtively, which is just like what peek
does compared to next
:-)
This post shares another super concise solution, just 3 lines of added code in total! And I just know too few about classes in C++ to come up with it...
// 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); 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) { // Initialize any member here. // **DO NOT** save a copy of nums and manipulate it directly. // You should only use the Iterator interface methods. } // Returns the next element in the iteration without advancing the iterator. int peek() { return Iterator(*this).next(); } // hasNext() and next() should behave the same as in the Iterator interface. // Override them if needed. int next() { return Iterator::next(); } bool hasNext() const { return Iterator::hasNext(); } };