Pattern visualizer
First Non-Repeating Character in a Stream
Re-scanning everything seen so far after each character is the obvious answer and it is quadratic. The insight is that 'first' means oldest, and a queue already stores things oldest-first — so the answer is never searched for, it is just the front. A character joins the back when it arrives; once its count passes one it is dead, but deleting it from the middle would cost a scan, so it is left in place and simply thrown away if it ever reaches the front. Every character is therefore pushed once and popped at most once, and each answer is a single peek. Animated on: stream = "aabcbd" — after every character, report the first character so far that has appeared exactly once, or '#' if there is none. The row drawn is the QUEUE of surviving candidates, not the stream..
The queue keeps candidates in arrival order, so the answer is always the front
'a' arrives and is brand new, so it joins the BACK of the queue as the newest candidate. The queue is now [a] — every character still in the running, in the order it showed up, which is exactly the order the answer has to be picked in.
1FUNCTION firstNonRepeating(stream)2 queue <- empty queue3 count <- empty map4 FOR EACH ch IN stream5 count[ch] <- count[ch] + 16 ENQUEUE ch INTO queue7 WHILE queue IS NOT EMPTY AND count[FRONT(queue)] > 18 DEQUEUE FROM queue9 IF queue IS EMPTY10 OUTPUT '#'11 ELSE12 OUTPUT FRONT(queue)
← / → step · space play · Home restart