Sorting array of exactly three unique repeating elements in JavaScript

Suppose we have an array of Numbers that contains any frequency of exactly three elements: -1, 0 and 1 like this:

const arr = [1, 1, 0, -1, 1, 0, -1, 1, 0, 0, 1];
console.log("Original array:", arr);
Original array: [ 1, 1, 0, -1, 1, 0, -1, 1, 0, 0, 1 ]

We are required to write a JavaScript function that takes in one such array. The function should simply sort this special array in place (without using any extra array to store the values). The only condition is that our function should be a linear time function using only one iteration.

Algorithm: Dutch National Flag

This problem is a variation of the Dutch National Flag algorithm. We use three pointers to partition the array:

  • left: Position where the next -1 should go
  • middle: Current element being processed
  • right: Position where the next 1 should go
Array Elements -1 values 0 values 1 values left pointer middle pointer right pointer

Implementation

const arr = [1, 1, 0, -1, 1, 0, -1, 1, 0, 0, 1];

const sortSpecialArray = (arr = []) => {
    const swap = (a, b) => {
        let temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    };
    
    let left = 0;
    let middle = 0;
    let right = arr.length - 1;
    
    while (middle <= right) {
        if (arr[middle] === -1) {
            swap(left++, middle++);
        } else if (arr[middle] === 0) {
            middle++;
        } else if (arr[middle] === 1) {
            swap(right--, middle);
        }
    }
};

sortSpecialArray(arr);
console.log("Sorted array:", arr);
Sorted array: [
  -1, -1, 0, 0, 0,
   0,  1, 1, 1, 1,
   1
]

How It Works

The algorithm processes each element once:

  • If current element is -1: Swap with left position, increment both left and middle
  • If current element is 0: Just move middle pointer forward
  • If current element is 1: Swap with right position, decrement right (don't increment middle as we need to check the swapped element)

Step-by-Step Example

const demonstrateSteps = () => {
    const arr = [1, 0, -1, 1, 0];
    console.log("Initial:", arr);
    
    let left = 0, middle = 0, right = 4;
    let step = 1;
    
    const swap = (a, b) => {
        [arr[a], arr[b]] = [arr[b], arr[a]];
    };
    
    while (middle <= right) {
        console.log(`Step ${step}: left=${left}, middle=${middle}, right=${right}, current=${arr[middle]}`);
        
        if (arr[middle] === -1) {
            swap(left++, middle++);
            console.log(`  Swapped -1 to left: ${arr}`);
        } else if (arr[middle] === 0) {
            middle++;
            console.log(`  0 in correct region: ${arr}`);
        } else if (arr[middle] === 1) {
            swap(right--, middle);
            console.log(`  Swapped 1 to right: ${arr}`);
        }
        step++;
    }
    
    console.log("Final sorted:", arr);
};

demonstrateSteps();
Initial: [ 1, 0, -1, 1, 0 ]
Step 1: left=0, middle=0, right=4, current=1
  Swapped 1 to right: [ 0, 0, -1, 1, 1 ]
Step 2: left=0, middle=0, right=3, current=0
  0 in correct region: [ 0, 0, -1, 1, 1 ]
Step 3: left=0, middle=1, right=3, current=0
  0 in correct region: [ 0, 0, -1, 1, 1 ]
Step 4: left=0, middle=2, right=3, current=-1
  Swapped -1 to left: [ -1, 0, 0, 1, 1 ]
Final sorted: [ -1, 0, 0, 1, 1 ]

Time and Space Complexity

Metric Complexity Explanation
Time O(n) Single pass through array
Space O(1) In-place sorting with constant extra space

Conclusion

The Dutch National Flag algorithm efficiently sorts arrays with three distinct values in linear time and constant space. This approach is optimal for problems involving exactly three unique elements, making it perfect for sorting arrays containing -1, 0, and 1.

Updated on: 2026-03-15T23:19:00+05:30

346 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements