AlgoMaster Logo

Sort Colors

Last Updated: March 29, 2026

medium
3 min read

Understanding the Problem

At first, this might seem like a straightforward sorting problem. Just sort the array and you're done. But the problem explicitly says we can't use a library sort function, and the follow-up asks for a single-pass solution. That's a strong hint that there's something cleverer going on here.

The critical observation is that we only have three distinct values: 0, 1, and 2. We're not sorting arbitrary numbers. We're partitioning the array into exactly three groups. This is fundamentally different from general sorting, and it opens the door to linear-time algorithms that don't rely on comparisons between arbitrary elements.

This problem is also known as the Dutch National Flag Problem, first proposed by Edsger Dijkstra. The idea is to partition an array into three sections around a pivot value, which in our case is 1 (white). Everything less than the pivot goes left, everything equal stays in the middle, and everything greater goes right.

Key Constraints:

  • 1 <= n <= 300 — With n at most 300, even O(n^2) is blazingly fast. But the follow-up asks for a one-pass O(n) solution with O(1) space, so the real challenge is algorithmic elegance, not performance.
  • nums[i] is either 0, 1, or 2 — Only three distinct values. This eliminates the need for general-purpose sorting. Counting or partitioning strategies become viable.
  • in-place — We can't create a new array for the result. Any solution must rearrange elements within the original array.

Approach 1: Counting Sort (Two Pass)

Intuition

The simplest idea is to take advantage of the fact that there are only three possible values. Just count how many times each value appears, then overwrite the array with the right number of 0s, followed by 1s, followed by 2s.

This is essentially counting sort adapted for a tiny alphabet. It's hard to get wrong, and it's a solid starting point.

Algorithm

  1. Iterate through nums and count the occurrences of 0, 1, and 2.
  2. Overwrite nums with count0 zeroes, then count1 ones, then count2 twos.

Example Walkthrough

1Pass 1: Count each color. Scanning index 0: value=2
0
2
i
1
0
2
2
3
1
4
1
5
0
1/5

Code

This approach works but requires two passes. Can we sort the array in a single pass by placing each element in its correct region as we encounter it?

Approach 2: Dutch National Flag (Three Pointers)

Intuition

This is the classic Dutch National Flag algorithm, designed by Dijkstra. The core idea is to maintain three regions in the array as we scan through it: everything before low is 0, everything between low and mid is 1, everything after high is 2, and everything between mid and high is unprocessed.

We use mid as our scanning pointer. If nums[mid] is 0, swap it with nums[low] and advance both. If it's 1, just advance mid. If it's 2, swap with nums[high] and shrink high, but don't advance mid because the swapped-in element hasn't been examined yet.

Algorithm

  1. Initialize low = 0, mid = 0, high = n - 1.
  2. While mid <= high:
    • If nums[mid] == 0: swap nums[mid] with nums[low], increment both low and mid.
    • If nums[mid] == 1: increment mid.
    • If nums[mid] == 2: swap nums[mid] with nums[high], decrement high (don't increment mid).
  3. When the loop ends, the array is sorted.

Example Walkthrough

1Initial: low=0, mid=0, high=5. All elements unprocessed.
0
low
2
mid
1
0
2
2
3
1
4
1
5
high
0
1/7

Code