Solution: Peeking Iterator
Tags: algorithms, javascript, leetcode, java
Published: 2021-02-08 10:51:06

*This is part of a series of Leetcode solution explanations ([index](https://dev.to/seanpgallivan/leetcode-solutions-index-57fl)). If you liked this solution or found it useful,* ***please like*** *this post and/or* ***upvote*** *[my solution post on Leetcode's forums](https://leetcode.com/problems/peeking-iterator/discuss/1055952/JS-Python-Java-C%2B%2B-Simple-Class-Solution-w-Explanation-or-beats-100-100).*

---

####[Leetcode Problem #284 (*Medium*): Peeking Iterator](https://leetcode.com/problems/peeking-iterator/)####

---

***Description:***

*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()`.*

---

***Examples:***

Example:||
|---:|---|
*Input:*|["PeekingIterator","next","peek","next","next","hasNext"]<br>[[[1,2,3]],[],[],[],[],[]]
*Output:*|[null,1,2,2,3,false]
*Explanation*|Assume that the iterator is initialized to the beginning of the list: [1,2,3].<br><br>Call next() gets you 1, the first element in the list.<br>Now you call peek() and it returns 2, the next element.<br>Calling next() after that still return 2.<br>You call next() the final time and it returns 3, the last element.<br>Calling hasNext() after that should return false.

---

***Idea:***

The trick here is realizing that you're not building the **class** from scratch. Instead, you're building a class that is constructed from *another* class instance.

Our new class will do the same things that the original class does, except that it will store the next value separately, so that we can **peek** at it without it being removed. The only challenging thing at this point is to make sure that the **next** function checks to make sure if there actually *is* a next element before updating the stored value.

---

***Javascript Code:***

The best result for the code below is **72ms / 39.0MB** (beats 93% / 83%).
```javascript
class PeekingIterator {
    constructor(iterator) {
        this.iterator = iterator
        this.nextVal = this.iterator.hasNext() ? this.iterator.next() : null
    };
    
    peek() {
        return this.nextVal
    };
    
    next() {
        let nextVal = this.nextVal
        this.nextVal = this.iterator.hasNext() ? this.iterator.next() : null
        return nextVal
    };
    
    hasNext() {
        return !!this.nextVal
    };
};
```

---

***Python Code:***

The best result for the code below is **20ms / 14.2MB** (beats 99% / 100%).
```python
class PeekingIterator:
    def __init__(self, iterator):
        self.iterator = iterator
        self.nextVal = self.iterator.next() if self.iterator.hasNext() else None
        
    def peek(self):
        return self.nextVal
        
    def next(self):
        nextVal = self.nextVal
        self.nextVal = self.iterator.next() if self.iterator.hasNext() else None
        return nextVal

    def hasNext(self):
        return bool(self.nextVal)
```

---

***Java Code:***

The best result for the code below is **4ms / 38.6MB** (beats 94% / 96%).
```java
class PeekingIterator implements Iterator<Integer> {
    Iterator<Integer> iter;
    Integer nextVal;
	
    public PeekingIterator(Iterator<Integer> iterator) {
	    iter = iterator;
        nextVal = iter.hasNext() ? iter.next() : null;
	}
	
	public Integer peek() {
        return nextVal;
	}
	
	@Override
    public Integer next() {
        Integer oldNext = nextVal;
        nextVal = iter.hasNext() ? iter.next() : null;
        return oldNext; 
    }
	
	@Override
	public boolean hasNext() {
	    return (nextVal != null);
	}
}
```

---

***C++ Code:***

The best result for the code below is **0ms / 7.3MB** (beats 100% / 94%).
```C++
class PeekingIterator : public Iterator {
public:
    int nextVal;
	
    PeekingIterator(const vector<int>& nums) : Iterator(nums) {
        nextVal = Iterator::hasNext() ? Iterator::next() : NULL;
	}
	
	int peek() {
        return nextVal;
	}
	
	int next() {
	    int oldNext = nextVal;
        nextVal = Iterator::hasNext() ? Iterator::next() : NULL;
        return oldNext; 
	}
	
	bool hasNext() const {
	    return (nextVal != NULL);
	}
};
```