Given an array A[] of 0s, 1s, and 2s of size N, the task is to write a function that can sort an array of 0s, 1s and 2s in ascending order such that 0s are in the beginning followed by all 1s and then 2s at the end, and without using any internal or inbuilt sorting function or library.
Input: {0, 1, 2, 0, 1, 2}
Output: {0, 0, 1, 1, 2, 2}
Input: {0, 1, 1, 0, 1, 2, 1, 2, 0, 0, 0, 1}
Output: {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2}
Well, there is no denying that that might be many approaches through which we can sort an array of 0s, 1s and 2s, but in this blog, we will only see 3 approaches that we think were the best and the easiest among all other approaches.
Let’s start…
In this approach, we are going to compare each number of the array with the one next to it while traversing the array from left to right. We can do this by using a nested loop system in which the outer loop will keep a track of the number and the inner loop will compare it with the rest of the elements of the array.
for(i=0 -> N)
{
for(j=i+1 -> N)
{
if(A[i] > A[j])
{
Swap(A[i], A[j])
}
}
}
Print A
package com.Tekolio.Arrays;
import java.util.Arrays;
public class Sort_0s_1s_2s {
public static void main(String[] args) {
int[] A = {0, 1, 2, 0, 1, 2};
int n = A.length;
for(int i=0; i<n; i++) {
for(int j=i+1; j<n; j++) {
if(A[i] > A[j]) {
int temp = A[i];
A[i] = A[j];
A[j] = temp;
}
}
}
System.out.print(Arrays.toString(A));
}
}
A[] = [0, 0, 1, 1, 2, 2]
Time Complexity – O(N^2) Space Complexity – O(1)
We all know the time complexity of a sorting algorithm in N log N, but the above approach is taking the time complexity of N^2 which is even higher. Let’s see how we can optimize it to O)N).
The idea behind this approach is to first count all the occurrences of 0s, 1s, and 2s in the array and then based on that counting place the elements in the array using a loop, and those count values as thor start and end indexes.
Int c0 = 0, c1 = 0, c2 = 0;
for(ii=0 -> N)
{
if(A[i] = 0) c0++
if(A[i] = 1) c1++
If(A[i] = 2) c2++
}
for(i=0 -> c0)
{
A[i] = 0;
}
for(i=c0 -> c0+c1
{
A[i] = 1;
}
for(int i=c1+c0 -> N)
{
A[i] = 2;
}
Print A;
package com.Tekolio.Arrays;
import java.util.Arrays;
public class Sort_0s_1s_2s {
public static void main(String[] args) {
int[] A = {0, 1, 2, 0, 1, 2};
int n = A.length;
int c0 = 0;
int c1 = 0;
int c2 = 0;
for(int i=0; i<n; i++) {
if(A[i] == 0) {
c0++;
}
if(A[i] == 1) {
c1++;
}
if(A[i] == 2) {
c2++;
}
}
for(int i=0; i<c0; i++) {
A[i] = 0;
}
for(int i=c0; i<c1+c0; i++) {
A[i] = 1;
}
for(int i=c1+c0; i<n; i++) {
A[i] = 2;
}
System.out.print(Arrays.toString(A));
}
}
A[] = [0, 0, 1, 1, 2, 2]
Time Complexity – O(N) Space Complexity – O(1)
Though the above approach is an optimized way to solve this problem there is still one problem, though the time complexity is linear but is not a perfect O(N) if analyzed correctly the time complexity of this approach is O(kN) and if we talk about this case, k=3 – time complexity of counting the 0s, 1s and 2s + the time complexity of placing them back into the array.
Now let’s a better approach than this which has a time complexity of O(N).
As the name suggests, this approach is dependent upon three-pointers which are usually named as low, mid, and high. These three pointers divide the array into four sections which are as follows –
Section 1
In this section, we will have all 0s and their range will be from 0 to low-1.
Section 2
Like the section 1 contains all 0s, this section will contain all 1s and its range will be from low to mid-1
Section 3
It will not contain any of the three values, or we can say posses unknown values which cannot predict and its range will be from mid to high – 1.
Section 4
This section will be from high to the end of the array and will contain all 2s.
The basic idea of this approach is to place all the zeros on the left of the array and the 2s on the right while keeping the 1s at the center of the array, and all this is possible in only a single traversal of the array making the time complexity of this approach a perfect O(N) i.e. without any coefficient attached to it.
Int low = 0, mid = 0, high = 0;
while(mid<=high)
{
if(A[mid] == 0)
{
swap(A[low], A[mid]);
low++;
mid++;
}
if(A[mid] == 1)
{
mid++;
}
if(A[mid] == 2)
{
swap(A[mid], A[high]);
high–;
}
}
Print A;
package com.Tekolio.Arrays;
import java.util.Arrays;
public class Sort_0s_1s_2s {
public static void main(String[] args) {
int[] A = {0, 1, 2, 0, 1, 2};
int low = 0;
int mid = 0;
int high = n-1;
while(mid <= high) {
if(A[mid] == 0) {
int temp = A[low];
A[low] = A[mid];
A[mid] = temp;
low++;
mid++;
}
if(A[mid] == 1) {
mid++;
}
if(A[mid] == 2) {
int temp = A [ mid ] ;
A [ mid ] = A [ high ] ;
A [ high ] = temp ;
high = high - 1 ;
}
}
System.out.print(Arrays.toString(A));
}
}
A[] = [0, 0, 1, 1, 2, 2]
Time Complexity – O(N) Space Complexity – O(1)
In this blog, we have discussed mainly 3 different ways in which we can sort an array of 0s, 1s, and 2s in such a way that 0s are in front followed by 1s and 2s at the end sorted array.
A single approach to that using the inbuilt sort functions and libraries to arrange them in ascending order, but that will take a time complexity of O(N log N) but we are told to do it in O(N) time complexity and O(1) space complexity. Thus we cannot use this method to sort the array.
So then we came up with some algorithms of ourselves like comparing the elements and arranging them in the ascending order, counting the number of zeros, ones, and twos and then placing them inside the array using that count, and lastly, the three-pointer approach which is also known Dutch National Flag Approach.
The time complexity of the brute force algorithm is O(N^2) as for the other two, they both have O(N) time complexity and we were asked to arrange the array in ascending order. And between the two approaches with O(N) time complexity, the three-pointer approach traverses the array only once, making it a perfect approach for O(N).
O(N)
Simple and efficient would be using the counting algorithm in which we count all the occurrences of 0s, 1s, and 2s in the array and place them in ascending order in the same array using a loop with start and end points same as the count of 0s, 1s and 2s
It is a programming problem proposed by Edsger Dijkstra. Here the task is to randomly arrange balls of white, red, and blue in such a way that balls of the same color are placed together. Or in the case of arrays, sort an array of 0, 1, and 2’s in linear time that does not consume any extra space.
We have to keep in mind that this algorithm can be implemented only on an array that has three unique elements.
Counting sort is a sorting algorithm that sorts the elements of an array by counting the number of occurrences of each unique element in the array. They are then stored in some random variables and used to sort arrays.
Inheritance in Java is a mechanism of creating a new class or interface from an…
In this blog, we will not only understand the concepts of OOPS in Java in…
Object-Oriented Programming System (OOPS) is a programming paradigm built around the concept of objects —…
Abstraction in Java is one of the four pillars of OOPs which is used to…
In this blog, we will learn How to Detect a Click Outside of a React…
learn How to Use Hooks to Create Infinite Scrolling in React by making a custom…