Sponsored
Sponsored
In this approach, we use an internal buffer variable to store the next element of the iterator. The key idea is to always keep the next element ready in this buffer when operations like `peek` are called. The `peek` method can return this buffered value, and the `next` method will return the buffered value while simultaneously updating the buffer with the new next element from the iterator.
Time Complexity: O(1) for all operations.
Space Complexity: O(1), as we only store single elements.
1class PeekingIterator:
2 def __init__(self, iterator):
3 self.iterator = iterator
4 self.next_element = next(iterator, None)
5
6 def peek(self):
7 return self.next_element
8
9 def next(self):
10 current = self.next_element
11 self.next_element = next(self.iterator, None)
12 return current
13
14 def hasNext(self):
15 return self.next_element is not None
In the Python solution, we use the Python built-in `next` to advance through the iterator and store the upcoming value in `self.next_element`. When `peek()` is called, it returns `self.next_element`. The `next()` method returns the stored `next_element` and updates it to the next element in the iterator. `hasNext()` checks if `self.next_element` is None to determine if there are more elements.
This approach leverages the iterator's facility by explicitly controlling its movement and caching the result for future references. It reads the next element so that `peek` can access it but avoids advancing through a list prematurely. Operations are efficient with constant time complexity for each of `peek`, `next`, and `hasNext`.
Time Complexity: O(1) for all operations.
Space Complexity: O(1).
1#include <vector>
2using namespace std;
3
4class PeekingIterator : public Iterator {
5 int nextElement;
bool hasPeeked;
public:
PeekingIterator(const vector<int>& nums) : Iterator(nums), hasPeeked(false) {}
int peek() {
if (!hasPeeked) {
nextElement = Iterator::next();
hasPeeked = true;
}
return nextElement;
}
int next() {
if (!hasPeeked) return Iterator::next();
hasPeeked = false;
return nextElement;
}
bool hasNext() const {
return hasPeeked || Iterator::hasNext();
}
};
The C++ solution leverages inheritance from the `Iterator` class, and the `hasPeeked` flag is used to track whether the next element has already been fetched. When `peek()` is called, it sets `nextElement` via `Iterator::next()` and `hasPeeked` to `true`. The `next()` function returns `nextElement` if `hasPeeked` is true and resets the flag. `hasNext()` is straightforward, returning `true` if either `hasPeeked` is true or `Iterator::hasNext()` is true.