DSA

Sort an array of 0's 1's and 2's

Covers: Brute Force: Sorting, Store freq of 0s, 1s and 2s, Dutch National Flag Algo. Optimal — Time O(n), Space O(1).

August 8, 2026

Given an array nums consisting of only 0, 1, or 2. Sort the array in non-decreasing order.

The sorting must be done in-place, without making a copy of the original array.

Brute Force: Sorting#

Apply a general-purpose sort to the array. Since the values are only 0, 1, or 2, any comparison-based sort will produce the correct order, but it does not exploit the very limited value domain and costs O(n log n) — significantly more work than a single pass.

cpp
class Solution {
public:
    void sortZeroOneTwo(vector<int>& nums) {
        sort(nums.begin(), nums.end());
    }
};

Time Complexity: O(nlogn)

Space Complexity: O(1)

Better Approach: Store freq of 0s, 1s and 2s#

Since the only possible values are 0, 1, and 2, count the occurrences of each in one pass and then overwrite the array: fill cnt0 zeros, followed by cnt1 ones, followed by cnt2 twos. This requires two passes but runs in O(n) total time with O(1) extra space — already better than sorting. The trade-off is two passes instead of one; the Dutch National Flag algorithm achieves the same result in a single pass.

cpp
class Solution {
public:
    void sortZeroOneTwo(vector<int>& nums) {
        int cnt0 = 0, cnt1 = 0, cnt2 = 0;

        for (int i = 0; i < nums.size(); i++) {
            if (nums[i] == 0) cnt0++;
            else if (nums[i] == 1) cnt1++;
            else cnt2++;
        }

        for (int i = 0; i < cnt0; i++) nums[i] = 0;

        for (int i = cnt0; i < cnt0 + cnt1; i++) nums[i] = 1; 
        
        for (int i = cnt0 + cnt1; i < nums.size(); i++) nums[i] = 2;
    }
};

Time Complexity: O(2*n)

Space Complexity: O(1)

Optimal Approach: Dutch National Flag Algo#

Edsger Dijkstra's Dutch National Flag algorithm partitions the array in a single pass using three pointers: low, mid, and high. The invariant maintained is [0s | 1s | unsorted | 2s]. When nums[mid] is 0, swap it with nums[low] and advance both low and mid. When it is 1, just advance mid. When it is 2, swap it with nums[high] and decrement high (do not advance mid yet, since the swapped element from the right is still unseen). The loop ends when mid > high, at which point the entire array is sorted. One pass, O(1) extra space.

  • Divide the array into three regions: [ 0s | 1s | unknown | 2s ]
  • And keep expanding these regions while scanning.
cpp
class Solution {
public:
    void sortZeroOneTwo(vector<int>& nums) {
        int low = 0, mid = 0, high=nums.size()-1;

        while(mid<=high){
            if(nums[mid]==0){
                swap(nums[low++], nums[mid++]);
            }else if(nums[mid]==1){
                mid++;
            }else{
                swap(nums[mid], nums[high--]);
            }
        } 
    }
};

Time Complexity: O(n)

Space Complexity: O(1)