Problem Description
Design an iterator that supports the peek operation on an existing iterator in addition to the next and hasNext operations. Implement a PeekingIterator class that pre-fetches the next element so that peek returns it without advancing the pointer.
Key Insights
- Use a buffered variable as a cache to store the next element.
- The peek method retrieves the cached element without modifying the underlying iterator.
- The next method returns the cached element (if available) and then updates the cache with the subsequent element.
- The hasNext method checks if the buffer has an element or if the underlying iterator has more elements.
Space and Time Complexity
Time Complexity: O(1) per operation (peek, next, and hasNext)
Space Complexity: O(1) additional space to store the cached element.
Solution
The approach is to maintain a single cached variable (buffer) that always holds the next element if one exists. During initialization, the cache is empty. The peek() method checks if the cache is populated; if not, it fetches the next element from the underlying iterator and caches it. The next() method returns the cached element if present and then refreshes the cache with the next element if possible. Otherwise, it directly returns the next element from the iterator. This lookahead mechanism ensures that peek() can always return the next element without advancing the iterator's pointer, allowing next() and hasNext() to behave as expected.