intermediate7 min read·Updated September 18, 2026
Dutch national flag (sort 0/1/2) Explained: Sorting [2, 0, 2, 1, 1, 0]
Master the Dutch national flag algorithm with a full walkthrough of [2, 0, 2, 1, 1, 0]. Build a solid mental model for three-way partitioning in O(n) time.
By Learnisim AI·Published September 18, 2026
LEARNING ARCSetup → Model in the example → Full trace → Twist → Edge cases → Apply
PREREQUISITES
- basic arrays
- pointer manipulation
Why
Why
Imagine you are handed an array of colored pebbles where every pebble is colored either red, white, or blue. In our locked working example, the array is given as , representing a chaotic mix of three distinct values. Your job is to group them so all the 0s come first, followed by all the 1s, and finally all the 2s, resulting in . If you reach for a standard comparison-based sorting algorithm like merge sort or quicksort, you will waste time comparing elements that you already know can only be 0, 1, or 2. Even worse, a general sort takes time and often requires extra memory, while we need to do this in-place with a single pass through the array. Without a specialized strategy, dealing with interleaved values like our initial forces clumsy multi-pass filtering where you scan once for 0s, scan again for 1s, and rewrite the array.
Model
The Three-Pointer Model for Three-Way Partitioning
When working with the locked example , a standard sorting algorithm takes time, which misses a crucial constraint: we only have three unique values ( and 2). Instead of comparing elements against each other arbitrarily, we can maintain three distinct pointers—, , and —to carve the array into four contiguous regions:
* Region 1 (0 to ): Contains all zeros (0).
* Region 2 ( to ): Contains all ones (1).
* Region 3 ( to ): Contains unexamined elements.
* Region 4 ( to ): Contains all twos (2).
* Region 2 ( to ): Contains all ones (1).
* Region 3 ( to ): Contains unexamined elements.
* Region 4 ( to ): Contains all twos (2).
As we scan through the array with , we inspect each unexamined element and route it to its proper home by swapping with either or . This single-pass mental model ensures every element is processed exactly once while preserving constant extra memory ( space).
Worked example
Tracing the Dutch National Flag Algorithm Step-by-Step
Let us execute our three-pointer model on the locked example: with . We initialize , , and . At each step, we examine the element at and apply our three pointer rules until .
Given:
Array , , , .
Array , , , .
Steps:
1. Iteration 1: . This is a
2. We swap with and decrement to 4.
- Array becomes:
- Pointers: , , . Notice that does not increment because the swapped value from index 5 is completely unexamined.
2. Iteration 2: . This is a 0. We swap with (no change), increment to 1, and increment to 1.
- Array remains:
- Pointers: , , .
3. Iteration 3: . This is a 0. We swap with , increment to 2, and increment to 2.
- Array remains:
- Pointers: , , .
4. Iteration 4: . This is a 2. We swap with and decrement to 3.
- Array becomes:
- Pointers: , , . Again, stays at 2 to inspect the newly swapped 1.
5. Iteration 5: . This is a 1. We simply increment to 3.
- Array remains:
- Pointers: , , .
6. Iteration 6: . This is a 1. We increment to 4.
- Array remains:
- Pointers: , , .
1. Iteration 1: . This is a
2. We swap with and decrement to 4.
- Array becomes:
- Pointers: , , . Notice that does not increment because the swapped value from index 5 is completely unexamined.
2. Iteration 2: . This is a 0. We swap with (no change), increment to 1, and increment to 1.
- Array remains:
- Pointers: , , .
3. Iteration 3: . This is a 0. We swap with , increment to 2, and increment to 2.
- Array remains:
- Pointers: , , .
4. Iteration 4: . This is a 2. We swap with and decrement to 3.
- Array becomes:
- Pointers: , , . Again, stays at 2 to inspect the newly swapped 1.
5. Iteration 5: . This is a 1. We simply increment to 3.
- Array remains:
- Pointers: , , .
6. Iteration 6: . This is a 1. We increment to 4.
- Array remains:
- Pointers: , , .
Result:
Since , the loop terminates. The final sorted array is , matching our expected output perfectly in exactly 6 iterations.
Since , the loop terminates. The final sorted array is , matching our expected output perfectly in exactly 6 iterations.
Try this: Trace the algorithm manually for nums = [2, 0, 1] with low = 0, i = 0, high = 2. What are the pointer values and array state after the first swap occurs?
Practice
Predicting the Partition: Step Through an Alternative Array
Now that you have seen the exact mechanics of how the three pointers ( and handle the standard working example , it is time to test your own predictive intuition. Consider a slightly modified starting array: . Set your initial pointers at and and step through the first two iterations manually. Pay special attention to what happens when encounters a 0 versus when it encounters a 2, and note why the pointer decreases without advancing when a 2 is swapped.
Apply
Beyond Three Colors: Generalizing the Partition Pattern
We have successfully tracked our initial array through a single-pass three-pointer scan, transforming it into . But the Dutch National Flag algorithm is more than a one-off trick for sorting three specific integer codes. The core mental model—maintaining boundaries with pointers while sweeping an active cursor through uncharted territory—is a universal blueprint for array segregation. Whenever you need to separate data into discrete buckets in linear time and constant space, you are essentially adapting this exact pointer-boundary invariant.
FAQ
How does the Dutch national flag algorithm sort [2, 0, 2, 1, 1, 0]?
It uses three pointers (low, mid, high) to partition the array in a single pass. Elements at mid are evaluated: 0s are swapped to the low boundary, 2s to the high boundary, and 1s are simply skipped, resulting in [0, 0, 1, 1, 2, 2].
Why is it called the Dutch National Flag problem?
Named by Edsger Dijkstra, the problem draws an analogy from the Dutch flag, which has three horizontal bands of red, white, and blue, representing the three distinct groups (0, 1, and 2) that need sorting.
What is the time and space complexity of this algorithm?
The time complexity is O(n) because every element is visited at most once by the mid pointer. The space complexity is O(1) as sorting is performed in-place with constant extra memory.
What are common pitfalls when implementing this algorithm?
A frequent mistake is incrementing the mid pointer after swapping a 2 with the high pointer. Since the swapped element coming from the high boundary is unexamined, mid must not advance until that element is evaluated.