Programming & Development / April 10, 2025

LeetCode 284: Peeking Iterator – Look Ahead Without Moving Forward

LeetCode 284 Peeking Iterator iterator design Python iterators peek operation object-oriented programming design pattern behavioral pattern wrapper class iterator extension

Introduction

LeetCode 284: Peeking Iterator is a classic object-oriented design problem. The task is to extend a given iterator so that it supports a peek() operation that returns the next element without advancing the iterator.

This problem is often seen in system design interviews and API design challenges, especially when wrapping lower-level APIs into smarter components.

Problem Statement

Design an iterator that supports the peek() operation — it returns the next element in the iteration without advancing the iterator. Implement the PeekingIterator class that:
  • Inherits from an existing Iterator class (assume it's already implemented).
  • Adds a peek() method.
  • Overrides next() and hasNext().

Example

python

Input: Iterator over [1,2,3]
Operations:
peek() → 1
next() → 1
next() → 2
peek() → 3
next() → 3
hasNext() → False

✅ Step-by-Step Solution

🧠 Core Idea

We need to add a peek() function, which shows the next element without moving the iterator.

To achieve this:

  • We cache the next element in a variable.
  • When peek() is called, we simply return this cached value.
  • next() returns the cached value and updates the cache with the next value (if any).
  • hasNext() checks whether anything is left.

✅ Python Code

We assume a simple Iterator class exists, like this:

python

class Iterator:
    def __init__(self, nums):
        self.nums = nums
        self.index = 0

    def hasNext(self):
        return self.index < len(self.nums)

    def next(self):
        val = self.nums[self.index]
        self.index += 1
        return val

Now we can implement PeekingIterator:

python

class PeekingIterator:
    def __init__(self, iterator: Iterator):
        self.iterator = iterator
        self.peeked = None
        if self.iterator.hasNext():
            self.peeked = self.iterator.next()

    def peek(self) -> int:
        return self.peeked

    def next(self) -> int:
        val = self.peeked
        self.peeked = self.iterator.next() if self.iterator.hasNext() else None
        return val

    def hasNext(self) -> bool:
        return self.peeked is not None

🧪 How It Works

Example: [1, 2, 3]

  1. Initialize: peeked = 1
  2. peek() → returns 1, doesn't move
  3. next() → returns 1, updates peeked = 2
  4. next() → returns 2, updates peeked = 3
  5. peek() → returns 3
  6. next() → returns 3, peeked = None
  7. hasNext() → False

⏱️ Time and Space Complexity

OperationTime ComplexitySpace Complexitypeek()O(1)O(1)next()O(1)O(1)hasNext()O(1)O(1)

🔍 Key Concepts

  • Lookahead Caching: This problem demonstrates a key design pattern of caching or lookahead buffering.
  • Wrapper Pattern: We’re wrapping an existing object (iterator) to extend its functionality.
  • Behavioral Design Pattern: It’s a classic example of enhancing behavior dynamically.

✅ Conclusion

LeetCode 284: Peeking Iterator is a neat design problem that tests your ability to wrap and extend existing functionality. It also introduces important software design ideas like:

  • Lookahead buffering
  • Object wrapping and method overriding
  • API enhancement



Comments

No comments yet

Add a new Comment

NUHMAN.COM

Information Technology website for Programming & Development, Web Design & UX/UI, Startups & Innovation, Gadgets & Consumer Tech, Cloud Computing & Enterprise Tech, Cybersecurity, Artificial Intelligence (AI) & Machine Learning (ML), Gaming Technology, Mobile Development, Tech News & Trends, Open Source & Linux, Data Science & Analytics

Categories

Tags

©{" "} Nuhmans.com . All Rights Reserved. Designed by{" "} HTML Codex