Editorial
Core insight
Sort Colors · Two Pointers
Core Insight for Sort Colors
The key intuition for solving LeetCode 75 efficiently lies in partitioning the array into three sections. Instead of sorting by comparison, we place elements into their respective "buckets" relative to the array indices.
We can maintain three regions within the array using pointers:
- Left Region: Strictly contains
0s. - Right Region: Strictly contains
2s. - Middle Region: Contains
1s and unprocessed elements.
To implement this, we need three pointers:
low: The boundary for0s. All elements before this index are0.high: The boundary for2s. All elements after this index are2.mid: The current element being evaluated.
The algorithm maintains the invariant that at any point during execution:
nums[0...low-1]are all0s.nums[high+1...n-1]are all2s.nums[low...mid-1]are all1s.
As mid traverses the array, we examine nums[mid] and swap it into the correct region (low or high) or leave it in the middle if it is a 1. This effectively shrinks the unknown region until the entire array is sorted.

Deep dive
Full breakdown
Full reasoning, pitfalls, and implementation flow
LeetCode 75: Sort Colors Solution & Explanation
Problem Overview
TL;DR: The optimal solution uses three pointers to partition the array into three distinct regions (0s, 1s, and 2s) in a single pass, swapping elements into their correct positions in-place.
The "Sort Colors" problem requires sorting an array nums containing n objects colored red, white, or blue. These colors are represented by the integers 0, 1, and 2, respectively. The goal is to sort the array in-place so that objects of the same color are adjacent, following the order red (0), white (1), and blue (2). This is a classic interview question often found in the LeetCode 75 study plan.
The constraints strictly forbid using the library's built-in sort function and suggest finding a one-pass algorithm using constant extra space.
Brute Force Approach for Sort Colors
A naive brute force approach would be to treat this as a generic sorting problem without leveraging the fact that there are only three distinct values. One might simply implement a standard sorting algorithm like Bubble Sort or use a library function (though prohibited by the problem statement for the optimal solution).
Another common sub-optimal approach is a two-pass "Counting Sort" logic:
- Iterate through the array to count the number of 0s, 1s, and 2s.
- Iterate through the array a second time to overwrite the array indices based on the counts (e.g., fill the first
count0indices with 0, the nextcount1indices with 1, etc.).
Pseudo-code (Counting Approach):
count0 = 0, count1 = 0, count2 = 0
for x in nums:
increment count of x
index = 0
for i from 0 to count0: nums[index++] = 0
for i from 0 to count1: nums[index++] = 1
for i from 0 to count2: nums[index++] = 2Complexity Analysis:
- Time Complexity: for generic sort, or for the two-pass counting approach.
- Space Complexity: or depending on the sort implementation.
Why it fails: While the counting approach is technically , it requires two passes over the data. The problem's follow-up explicitly asks for a one-pass algorithm. Furthermore, generic sorting does not utilize the limited cardinality of the input elements (only 3 values).
Algorithm Strategy: Two Pointer Patterns
-
Initialization:
- Initialize
lowat the start of the array (index 0). - Initialize
highat the end of the array (indexn-1). - Initialize
midat the start of the array (index 0).
- Initialize
-
Traversal:
- Loop while
midis less than or equal tohigh. This ensures we process every element that hasn't been placed in the2s region yet.
- Loop while
-
Decision Logic (at
nums[mid]):- Case 0: If the current element is
0, it belongs in the Left Region. Swapnums[mid]withnums[low]. Increment bothlowandmid. - Case 1: If the current element is
1, it is already in the correct relative position (Middle Region). Simply incrementmid. - Case 2: If the current element is
2, it belongs in the Right Region. Swapnums[mid]withnums[high]. Decrementhigh. Crucial: Do not incrementmidhere, because the element swapped fromhighhas not been inspected yet and could be a0or2.
- Case 0: If the current element is
-
Termination:
- The process ends when
midcrosseshigh. At this point, all boundaries meet, and the array is fully partitioned.
- The process ends when
Execution Flow
Consider nums = [2, 0, 2, 1, 1, 0].
-
Start:
low=0,mid=0,high=5.nums[mid]is2.- Swap
nums[0]andnums[5]. Array:[0, 0, 2, 1, 1, 2]. - Decrement
highto 4.midstays 0.
-
Step 2:
low=0,mid=0,high=4.nums[mid]is0.- Swap
nums[0]andnums[0](self-swap). Array:[0, 0, 2, 1, 1, 2]. - Increment
lowto 1,midto 1.
-
Step 3:
low=1,mid=1,high=4.nums[mid]is0.- Swap
nums[1]andnums[1]. Array:[0, 0, 2, 1, 1, 2]. - Increment
lowto 2,midto 2.
-
Step 4:
low=2,mid=2,high=4.nums[mid]is2.- Swap
nums[2]andnums[4]. Array:[0, 0, 1, 1, 2, 2]. - Decrement
highto 3.midstays 2.
-
Step 5:
low=2,mid=2,high=3.nums[mid]is1.- Increment
midto 3.
-
Step 6:
low=2,mid=3,high=3.nums[mid]is1.- Increment
midto 4.
-
End:
mid(4) >high(3). Loop terminates. Result:[0, 0, 1, 1, 2, 2].
Proof of Correctness
The correctness relies on the loop invariant involving the three partitions.
- Invariant:
[0, low)contains 0s,(high, n-1]contains 2s, and[low, mid)contains 1s. - Initialization: Initially, all ranges are empty, so the invariant holds trivially.
- Maintenance:
- When we see a
0, we swap it tolow, extending the0s range and shifting the1s range. - When we see a
1, we extend the1s range by movingmid. - When we see a
2, we swap it tohigh, extending the2s range.
- When we see a
- Termination: Since
midincreases orhighdecreases at every step, the unclassified window[mid, high]shrinks to zero. When the loop finishes, the entire array is covered by the three sorted partitions.
Pattern Reuse Notes
The "Two Pointers - In-place Array Modification" pattern is highly versatile. Understanding how to partition arrays using pointers is essential for the following problems:
- LeetCode 26: Remove Duplicates from Sorted Array - Uses a read/write pointer pair to partition unique elements from duplicates.
- LeetCode 27: Remove Element - Uses pointers to separate target values from the rest of the array.
- LeetCode 80: Remove Duplicates from Sorted Array II - An extension of LeetCode 26 allowing at most two duplicates.
- LeetCode 283: Move Zeroes - Essentially a simplified version of Sort Colors where we partition
0s and non-0s.
Feynman coach · Before you peek at the code
Can you explain the core insight in your own words?
If you can explain it before reading code, you’re far more likely to recall it under interview pressure.
Reference Implementation
C++ Solution for LeetCode 75
1class Solution {
2public:
3 void sortColors(vector<int>& nums) {
4 int low = 0;
5 int mid = 0;
6 int high = nums.size() - 1;
7
8 while (mid <= high) {
9 if (nums[mid] == 0) {
10 // Swap current element to the 0s boundary
11 swap(nums[low], nums[mid]);
12 low++;
13 mid++;
14 } else if (nums[mid] == 1) {
15 // 1s are in the middle, just move forward
16 mid++;
17 } else {
18 // Swap current element to the 2s boundary
19 swap(nums[mid], nums[high]);
20 high--;
21 // Do not increment mid; we need to check the swapped value
22 }
23 }
24 }
25};Java Solution for LeetCode 75
1class Solution {
2 public void sortColors(int[] nums) {
3 int low = 0;
4 int mid = 0;
5 int high = nums.length - 1;
6
7 while (mid <= high) {
8 if (nums[mid] == 0) {
9 int temp = nums[low];
10 nums[low] = nums[mid];
11 nums[mid] = temp;
12 low++;
13 mid++;
14 } else if (nums[mid] == 1) {
15 mid++;
16 } else {
17 int temp = nums[high];
18 nums[high] = nums[mid];
19 nums[mid] = temp;
20 high--;
21 // Note: mid is NOT incremented here
22 }
23 }
24 }
25}Python Solution for LeetCode 75
1class Solution:
2 def sortColors(self, nums: List[int]) -> None:
3 """
4 Do not return anything, modify nums in-place instead.
5 """
6 low, mid, high = 0, 0, len(nums) - 1
7
8 while mid <= high:
9 if nums[mid] == 0:
10 nums[low], nums[mid] = nums[mid], nums[low]
11 low += 1
12 mid += 1
13 elif nums[mid] == 1:
14 mid += 1
15 else: # nums[mid] == 2
16 nums[high], nums[mid] = nums[mid], nums[high]
17 high -= 1
18 # Do not increment mid here