Open In App

Segregate 0s and 1s in an array

Last Updated : 07 Nov, 2024
Summarize
Comments
Improve
Suggest changes
Like Article
Like
Share
Report
News Follow

You are given an array of 0s and 1s in random order. Segregate 0s on left side and 1s on right side of the array [Basically you have to sort the array]. Traverse array only once. 

Input : [0, 1, 0, 1, 0, 0, 1, 1, 1, 0]
Output : [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]

Input : [0, 1, 0]
Output : [0, 0, 1]

Input : [1, 1]
Output : [1, 1]

Input : [0]
Output : [0]

Naive Approach – Count 1s and 0s – Two Traversals

Let’s understand with an example we have an array arr = [0, 1, 0, 1, 0, 0, 1] the size of the array is 7 now we will traverse the entire array and find out the number of zeros in the array, In this case the number of zeros is 4 so now we can easily get the number of Ones in the array by Array Length – Number Of Zeros. Once we have counted, we can fill the array first we will put the zeros and then ones (we can get number of ones by using above formula).

C++
#include <iostream>
#include <vector>
using namespace std;

// Function to segregate 0s and 1s
void segregate0and1(vector<int>& arr) {
  
    // Count 0s
    int count = 0; 
    for (int x : arr)
        if (x == 0)
            count++;

    // Fill the vector with 0s until count
    for (int i = 0; i < count; i++)
        arr[i] = 0;

    // Fill the remaining vector space with 1s
    for (int i = count; i < arr.size(); i++)
        arr[i] = 1;
}

int main() {
    vector<int> arr = { 0, 1, 0, 1, 1, 1 };

    segregate0and1(arr);
    cout << "Array after segregation is ";
    for (int x : arr)
        cout << x << " ";

    return 0;
}
C Java Python C# JavaScript PHP

Output
Array after segregation is 0 0 1 1 1 1 

Time Complexity : O(n) 
Auxiliary Space: O(1)

The above solution has two issues

  • Requires two traversals of the array.
  • If 0s and 1s represent keys (say 0 means first year students and 1 means second year) of large objects associated, then the above solution would not work.

Expected Approach – One Traversal

Maintain two indexes. Initialize the first index left as 0 and second index right as n-1.
Do following while lo < hi 
…a) Keep incrementing index lo while there are 0s at it 
…b) Keep decrementing index hi while there are 1s at it 
…c) If lo < hi then exchange arr[lo] and arr[hi]

C++
#include <iostream>
#include <vector>
using namespace std;

/* Function to put all 0s on the left and all 1s on the right */
void segregate0and1(vector<int>& arr) {
  
    // Initialize lo and hi indexes
    int lo = 0, hi = arr.size() - 1; 

    while (lo < hi) {
      
        // Increment lo index while we see 0 at lo
        while (arr[lo] == 0 && lo < hi)
            lo++;

        // Decrement hi index while we see 1 at hi
        while (arr[hi] == 1 && lo < hi)
            hi--;

        // If lo is smaller than hi, then there is 
        // a 1 at lo and a 0 at hi
        if (lo < hi) {
            swap(arr[lo], arr[hi]);
            lo++;
            hi--;
        }
    }
}

int main() {
    vector<int> arr = {0, 1, 0, 1, 1, 1};

    segregate0and1(arr);

    cout << "Array after segregation: ";
    for (int x : arr)
        cout << x << " ";
    return 0;
}
C Java Python C# JavaScript

Output
Array after segregation: 0 0 1 1 1 1 

Time Complexity : O(n) 
Auxiliary Space: O(1)

The above approach is mainly derived from Hoare’s Partition Algorithm in QuickSort

More Efficient Implementation of the Above Approach
1. Take two pointer lo (for element 0) starting from beginning (index = 0) and hi(for element 1) starting from end (index = array.length-1). 
Initialize lo = 0 and hi = array.length-1 
2. It is intended to Put 1 to the right side of the array. Once it is done, then 0 will definitely towards the left side of the array.

C++
#include <iostream>
#include <vector>
using namespace std;

// Function to put all 0s on the left and 
// all 1s on the right
void segregate0and1(vector<int>& arr) {
    int lo = 0;
    int hi = arr.size() - 1;

    while (lo < hi) {
      
        // If we have a 1 at lo
        if (arr[lo] == 1) {
          
            // And a 0 at hi
            if (arr[hi] != 1) {
                swap(arr[lo], arr[hi]);
                lo++;
                hi--;
            }
            else {          
                hi--;
            }  
        } else {
            lo++;
        }
    }
}

int main() {
    vector<int> arr = {0, 1, 0, 1, 1, 1};

    segregate0and1(arr);

    cout << "Array after segregation is ";
    for (int x : arr)
        cout << x << " ";

    return 0;
}
C Java Python C# JavaScript

Output
Array after segregation is 0 0 1 1 1 1 


 



Next Article

Similar Reads

three90RightbarBannerImg