cconnected.
Understand the pattern. Find your own way.Find your starting point
Your learning feed/Idea 34 of 218
Ideas this builds on
Arrays, search & sorting34 / 218

Dutch flag: grow three regions

Picture

Arrange [2,0,2,1,1,0] so every 0 precedes every 1, which precedes every 2.

Predict

After swapping a 2 with the unknown right edge, may the scan always advance?

Walk through the small example

No. Each value belongs to one of three regions, and one unknown item is classified per iteration.

Mental model and complete Python solution

Do not think “sorting.” Think “classify the next unknown.” The invariant makes every swap’s destination obvious and guarantees the unknown region shrinks.

What the function promises: Mutate and return a list containing only integers 0, 1, and 2. Reject other values before mutation.

def sort_colors(values):
    if any(value not in (0, 1, 2) for value in values):
        raise ValueError("Only 0, 1, 2 are allowed")
    low = scan = 0
    high = len(values) - 1
    while scan <= high:
        if values[scan] == 0:
            values[low], values[scan] = values[scan], values[low]
            low += 1; scan += 1
        elif values[scan] == 1:
            scan += 1
        else:
            values[scan], values[high] = values[high], values[scan]
            high -= 1
    return values

assert sort_colors([2,0,2,1,1,0]) == [0,0,1,1,2,2]

Work and storage: O(n) time and O(1) extra space.

When to recognize it: Each value belongs to one of three regions, and one unknown item is classified per iteration.

Check before applying it: Advancing after a right swap can skip an unclassified incoming value.

Change one rule

There are many categories.

See what changes

Use counting for a small key range or a general sorting method; the three-region invariant does not scale directly.

Connect

invariants: Each pointer boundary gives a region a precise meaning.

Quicksort: partition around a pivot: This is a three-way partition around a middle value.