Peeking Iterator - Problem
Design a Peeking Iterator - Create an enhanced iterator that extends the functionality of a standard iterator by adding a
You're given a basic iterator that supports
Key Requirements:
The challenge is maintaining the iterator's state while supporting the peek functionality efficiently. This pattern is commonly used in parsers, tokenizers, and streaming data processors where you need to make decisions based on upcoming elements.
peek() operation.You're given a basic iterator that supports
next() and hasNext() operations. Your task is to implement a PeekingIterator class that adds the ability to look ahead at the next element without consuming it.Key Requirements:
next()- Returns the next element and advances the iteratorhasNext()- Returns true if more elements existpeek()- Returns the next element without advancing the iterator
The challenge is maintaining the iterator's state while supporting the peek functionality efficiently. This pattern is commonly used in parsers, tokenizers, and streaming data processors where you need to make decisions based on upcoming elements.
Input & Output
example_1.py โ Basic Usage
$
Input:
Iterator: [1, 2, 3]
Operations: ["peek", "next", "peek", "next", "hasNext"]
โบ
Output:
[1, 1, 2, 2, true]
๐ก Note:
peek() returns 1 without advancing, next() returns 1 and advances, peek() returns 2, next() returns 2 and advances, hasNext() returns true since 3 remains
example_2.py โ Multiple Peeks
$
Input:
Iterator: [1, 2]
Operations: ["peek", "peek", "next", "peek", "next", "hasNext"]
โบ
Output:
[1, 1, 1, 2, 2, false]
๐ก Note:
Multiple consecutive peeks return the same value without advancing. After consuming all elements, hasNext() returns false
example_3.py โ Single Element
$
Input:
Iterator: [42]
Operations: ["hasNext", "peek", "hasNext", "next", "hasNext"]
โบ
Output:
[true, 42, true, 42, false]
๐ก Note:
Single element case - peek doesn't affect hasNext() result until element is consumed via next()
Visualization
Tap to expand
Understanding the Visualization
1
Initial State
Iterator is ready, no element cached yet
2
First Peek
Cache the next element from underlying iterator
3
Multiple Peeks
Return cached element without re-fetching
4
Next Operation
Return cached element and clear cache
5
Direct Next
If no cache, directly get from underlying iterator
Key Takeaway
๐ฏ Key Insight: The optimal solution balances memory efficiency with functionality by caching only what's needed, when it's needed - a perfect example of lazy evaluation in iterator design.
Time & Space Complexity
Time Complexity
O(1)
All operations (peek, next, hasNext) are constant time
โ Linear Growth
Space Complexity
O(1)
Only stores one cached element and iterator reference
โ Linear Space
Constraints
- 1 โค nums.length โค 1000
- -1000 โค nums[i] โค 1000
- At most 1000 calls will be made to next(), hasNext(), and peek()
- Follow up: How would you extend this to support multiple peek() calls ahead?
๐ก
Explanation
AI Ready
๐ก Suggestion
Tab
to accept
Esc
to dismiss
// Output will appear here after running code