A price feed merges several lists of integer ticks by taking turns: one value from the first list, one from the second, and so on, then back to the first. Build that merger as an iterator.
Implement class InterleaveIterator:
InterleaveIterator(arrays: list[list[int]], cycle: bool): the lists take turns in the order given. The caller never modifies the lists afterwards.has_next() -> bool: is there another value?next() -> int: return the next value. If there is none, raiseStopIteration.
What happens when a list runs out depends on cycle:
cycle=False: a list that has run out drops out of the rotation; the others keep taking turns. Iteration ends when every list has run out.cycle=True: a list that has run out starts again from its first value on its next turn, so iteration never ends. The one exception: if every list is empty, there is nothing to produce andhas_next()isFalsestraight away.
Empty lists never produce anything and are simply skipped in both modes.
it = InterleaveIterator([[1, 2, 3], [], [7], [8, 9]], cycle=False)
[it.next() for _ in range(6)] # [1, 7, 8, 2, 9, 3]
it.has_next() # False
it = InterleaveIterator([[1, 2, 3], [], [7], [8, 9]], cycle=True)
[it.next() for _ in range(10)] # [1, 7, 8, 2, 7, 9, 3, 7, 8, 1]
InterleaveIterator([[], []], cycle=True).has_next() # False
Constraints: up to 100,000 lists and 200,000 values in total. has_next() may be called any number of times between next() calls and must not skip anything. Both methods must be amortized O(1): don't walk past exhausted or empty lists again and again.
Show hint
Keep a queue of (list, position) for the lists that can still produce something. next() pops the front, takes one value, and pushes it back if it still has values (or, with cycle, after resetting its position to 0).