1. Problem Statement
You are given an array consisting of only 0s, 1s, and 2s. Your task is to sort the array in-place so that all 0s come first, followed by all 1s, and then all 2s.
Example:
Input: arr = [2, 0, 2, 1, 1, 0] Output: arr = [0, 0, 1, 1, 2, 2]
2. Why Is It Called the “Dutch National Flag Problem”?
The algorithm is called the Dutch National Flag Algorithm because it was proposed by Edsger W. Dijkstra, a renowned Dutch computer scientist, to model a problem inspired by the colors of the Dutch national flag, which consists of three distinct colors:
- Red
- White
- Blue
Dijkstra used these three colors to represent three categories or groups in an array, and he designed an efficient algorithm to sort them in a single pass — just like arranging the flag colors in the correct order.
3. Metaphorical Explanation
Imagine a collection of red, white, and blue balls in a line (unsorted). The goal is to sort them into a proper Dutch flag layout:
[ RED | WHITE | BLUE ]
Now replace:
- Red → 0
- White → 1
- Blue → 2
The algorithm groups all similar elements together in a specific order using three pointers (low, mid, high) and in-place swapping.
4. What makes it optimal?
The Dutch National Flag Algorithm is optimal because it sorts the array in a single pass, using constant space, and no nested loops or counting operations. It efficiently partitions the array into three sections using in-place swaps, and handles every element exactly once.
This approach avoids the inefficiencies of:
- Two-pass counting methods, where we count occurrences and then write values again.
- General-purpose sorting algorithms, which take more than linear time and unnecessary comparisons.
5. Algorithm Steps
We use three pointers:
low: points to the position where the next0should go.mid: scans the array and evaluates each value.high: points to the position where the next2should go.
Initially:
low = 0mid = 0high = n - 1
We loop while mid <= high. Inside the loop, we inspect arr[mid]:
Case 1: arr[mid] == 0
- This element belongs to the start of the array.
- We swap
arr[mid]witharr[low]to move the0into the correct zone. - Then we increment both
lowandmidbecause both positions now hold valid sorted values.
Case 2: arr[mid] == 1
- This element is already in the correct middle position.
- We simply increment
midand move on.
Case 3: arr[mid] == 2
- This element belongs at the end of the array.
- We swap
arr[mid]witharr[high]to move the2into the correct zone. - Then we decrement
high, but we do not incrementmid, because the swapped value atmidcould be a0,1, or2— and we need to check it.
6. Why It Works: Logical Justification
- By moving
0s to the left and2s to the right as soon as we see them, the array is progressively sorted from both ends inward. 1s are naturally left in the middle without needing to be moved unless surrounded by unsorted elements.- Since each value is handled based on its class (
0,1, or2), we avoid the need for any comparisons between elements — we only check values directly.
7. Visual Representation
We visualize the array and three pointers low, mid, and high:
Initial: [2, 0, 2, 1, 1, 0]
L M H
After 1: [0, 0, 2, 1, 1, 2]
L M H
After 2: [0, 0, 2, 1, 1, 2]
L M H
After 3: [0, 0, 1, 1, 2, 2]
L M H
After 4: [0, 0, 1, 1, 2, 2]
M H
After 5: [0, 0, 1, 1, 2, 2]
M>H => STOP
8. Java Implementation
public class DutchNationalFlag {
public static void sortColors(int[] arr) {
int low = 0, mid = 0;
int high = arr.length - 1;
while (mid <= high) {
switch (arr[mid]) {
case 0: // Swap arr[mid] and arr[low]
int temp0 = arr[low];
arr[low] = arr[mid];
arr[mid] = temp0;
low++;
mid++;
break;
case 1: // Just move mid
mid++;
break;
case 2: // Swap arr[mid] and arr[high]
int temp2 = arr[mid];
arr[mid] = arr[high];
arr[high] = temp2;
high--;
// Note: Don't move mid here!
break;
}
}
}
public static void main(String[] args) {
int[] arr = {2, 0, 2, 1, 1, 0};
sortColors(arr);
for (int num : arr) {
System.out.print(num + " ");
}
}
}
