↓Skip to main content
  1. LeetCode/

LeetCode 281: Zigzag Iterator

·2 mins· ·
LeetCode Medium Queue Design Iterator
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: medium First Attempt: 2026-04-29

  • Submissions: Accepted (first try)

Approach
#

Output one element from each array in turn; once one runs out, output the rest of the other.

My Solution: two deques and a whose-turn flag
#

def hasNext(self) -> bool:
    if self.next_pop == "v1":
        if self.queue1:
            return True
        elif self.queue2:
            self.next_pop = "v2"
            return True
        return False
    ...

hasNext also handles “if it is this side’s turn but it is empty, switch sides”. It passes, but the logic for the two sides is duplicated, and the follow-up “what about k arrays?” would need many changes.

Better: a queue of sources
#

The queue holds sources that still have elements, together with each source’s current position. Each next takes the source at the front and reads one value; if the source has more, it goes back to the end of the queue:

from collections import deque

class ZigzagIterator:
    def __init__(self, v1: List[int], v2: List[int]):
        self.q = deque((v, 0) for v in (v1, v2) if v)

    def next(self) -> int:
        v, i = self.q.popleft()
        if i + 1 < len(v):
            self.q.append((v, i + 1))
        return v[i]

    def hasNext(self) -> bool:
        return bool(self.q)

Supporting k arrays only means putting k sources in the queue at construction, and hasNext no longer has side effects.

Complexity
#

next and hasNext are O(1); space O(k), excluding the input arrays.

Mistakes to Avoid
#

  • Putting empty arrays in the queue: a later next reads out of range.
  • Giving hasNext side effects: repeated calls must return the same result.

Interview Explanation
#

A queue stores each source that still has elements, plus its current position. Each next reads one value from the source at the front and puts it back at the end if it has more, which naturally alternates and drops exhausted sources. hasNext just checks whether the queue is empty. Generalizing to k arrays means putting all k sources in the queue, and every operation stays O(1).

Related

LeetCode 3829: Design Ride Sharing System
·2 mins
LeetCode Medium Queue Design Hash-Map Lazy-Deletion
LeetCode 3829 note: one queue each for riders and drivers; cancellations only update a set, and canceled riders at the front are dropped before matching
LeetCode 3508: Implement Router
·3 mins
LeetCode Medium Design Binary-Search Queue Hash-Map
LeetCode 3508 note: a queue for FIFO, a set for duplicates, and an increasing time list per destination queried with bisect
LeetCode 3885: Design Event Manager
·2 mins
LeetCode Medium Heap Design Hash-Map Lazy-Deletion
LeetCode 3885 note: a dict of current priorities plus a max-heap with lazy deletion, validated on pop
LeetCode 1570: Dot Product of Two Sparse Vectors
·2 mins
LeetCode Medium Two-Pointers Design Hash-Table Array
LeetCode 1570 note: store only non-zero (index, value) pairs, and compute the dot product by merging the two index-sorted lists with two pointers, multiplying only on equal indices
LeetCode 3835: Count Subarrays With Cost Less Than or Equal to K
·2 mins
LeetCode Medium Sliding-Window Monotonic-Queue Queue Array
LeetCode 3835 note: cost = (max - min) × length only grows as the window grows, so a sliding window counts subarrays; two monotonic deques keep the window’s max and min
LeetCode 244: Shortest Word Distance II
·2 mins
LeetCode Medium Two-Pointers Design Hash-Table String Array
LeetCode 244 note: precompute each word’s positions (sorted by construction), then answer each query by merging the two position lists with two pointers, always advancing the smaller one