~/problems / Iterators & parsers / Iterators and generators

OA: Flatten a 2D array, with remove

easy 2 levels ~25 min Airbnb

Level 1 Walking a jagged 2D list

Build an iterator over a list of rows of integers that hands out the numbers one at a time: all of row 0 from left to right, then row 1, and so on. Rows can have different lengths, and any row may be empty.

class Vector2D:
    def __init__(self, rows: list[list[int]]): ...
    def has_next(self) -> bool: ...
    def next(self) -> int: ...
  • has_next() tells whether another number is left. Calling it repeatedly must not skip anything.
  • next() returns the next number and advances. It is only called when has_next() would return True.
  • Don't build a flattened copy (use O(1) extra space), and don't modify the caller's lists.

Both methods must be amortised O(1): the tests use 300,000 rows, most of them empty, and call has_next() before every next(). Rescanning from the first row each time is far too slow.

it = Vector2D([[1, 2], [], [3], [], []])
it.next()      # 1
it.next()      # 2
it.has_next()  # True
it.has_next()  # True
it.next()      # 3
it.has_next()  # False: trailing empty rows hold nothing
Show hint

Keep two indexes (row, col) into rows. Write a helper that moves (row, col) forward past exhausted and empty rows, and call it from both methods.

Level 2 unlocks when level 1 passes.

Topic: Iterators and generators. Resumable/serializable iterators, merging streams, lazy pipelines.

0:00
Ctrl ' run · Ctrl ↵ submit
esc