Given an array of 0’s and 1’s, we need to write a program to find the minimum number of swaps required to group all 1’s present in the array together.
Examples:
Input : arr[] = {1, 0, 1, 0, 1}
Output : 1
Explanation: Only 1 swap is required to
group all 1's together. Swapping index 1
and 4 will give arr[] = {1, 1, 1, 0, 0}
Input : arr[] = {1, 0, 1, 0, 1, 1}
Output : 1
A simple solution is to first count total number of 1’s in the array. Suppose this count is x, now we need to find the subarray of length x of this array with maximum number of 1’s. And minimum swaps required will be the number of 0’s in the subarray of length x with maximum number of 1’s.
Time Complexity: O(n2)
An efficient solution is to optimize the brute force technique of finding the subarray in above approach using the concept of sliding window technique. We can maintain a preCount array to find number of 1’s present in a subarray in O(1) time complexity.
Below is the implementation of above idea:
C++
#include <iostream>
#include <limits.h>
using namespace std;
int minSwaps( int arr[], int n) {
int noOfOnes = 0;
for ( int i = 0; i < n; i++) {
if (arr[i] == 1)
noOfOnes++;
}
int x = noOfOnes;
int maxOnes = INT_MIN;
int preCompute[n] = {0};
if (arr[0] == 1)
preCompute[0] = 1;
for ( int i = 1; i < n; i++) {
if (arr[i] == 1) {
preCompute[i] = preCompute[i - 1] + 1;
} else
preCompute[i] = preCompute[i - 1];
}
for ( int i = x - 1; i < n; i++) {
if (i == (x - 1))
noOfOnes = preCompute[i];
else
noOfOnes = preCompute[i] - preCompute[i - x];
if (maxOnes < noOfOnes)
maxOnes = noOfOnes;
}
int noOfZeroes = x - maxOnes;
return noOfZeroes;
}
int main() {
int a[] = {1, 0, 1, 0, 1};
int n = sizeof (a) / sizeof (a[0]);
cout << minSwaps(a, n);
return 0;
}
|
Java
import java.io.*;
class GFG {
static int minSwaps( int arr[], int n) {
int noOfOnes = 0 ;
for ( int i = 0 ; i < n; i++) {
if (arr[i] == 1 )
noOfOnes++;
}
int x = noOfOnes;
int maxOnes = Integer.MIN_VALUE;
int preCompute[] = new int [n];
if (arr[ 0 ] == 1 )
preCompute[ 0 ] = 1 ;
for ( int i = 1 ; i < n; i++) {
if (arr[i] == 1 ) {
preCompute[i] = preCompute[i - 1 ] + 1 ;
} else
preCompute[i] = preCompute[i - 1 ];
}
for ( int i = x - 1 ; i < n; i++) {
if (i == (x - 1 ))
noOfOnes = preCompute[i];
else
noOfOnes = preCompute[i] - preCompute[i - x];
if (maxOnes < noOfOnes)
maxOnes = noOfOnes;
}
int noOfZeroes = x - maxOnes;
return noOfZeroes;
}
public static void main (String[] args) {
int a[] = { 1 , 0 , 1 , 0 , 1 };
int n = a.length;
System.out.println( minSwaps(a, n));
}
}
|
Python3
def minSwaps(arr,n):
noOfOnes = 0
for i in range (n):
if (arr[i] = = 1 ):
noOfOnes = noOfOnes + 1
x = noOfOnes
maxOnes = - 2147483648
preCompute = {}
if (arr[ 0 ] = = 1 ):
preCompute[ 0 ] = 1
for i in range ( 1 ,n):
if (arr[i] = = 1 ):
preCompute[i] = preCompute[i - 1 ] + 1
else :
preCompute[i] = preCompute[i - 1 ]
for i in range (x - 1 ,n):
if (i = = (x - 1 )):
noOfOnes = preCompute[i]
else :
noOfOnes = preCompute[i] - preCompute[i - x]
if (maxOnes < noOfOnes):
maxOnes = noOfOnes
noOfZeroes = x - maxOnes
return noOfZeroes
a = [ 1 , 0 , 1 , 0 , 1 ]
n = len (a)
print (minSwaps(a, n))
|
C#
using System;
class GFG {
static int minSwaps( int []arr, int n) {
int noOfOnes = 0;
for ( int i = 0; i < n; i++) {
if (arr[i] == 1)
noOfOnes++;
}
int x = noOfOnes;
int maxOnes = int .MinValue;
int []preCompute = new int [n];
if (arr[0] == 1)
preCompute[0] = 1;
for ( int i = 1; i < n; i++) {
if (arr[i] == 1) {
preCompute[i] = preCompute[i - 1] + 1;
} else
preCompute[i] = preCompute[i - 1];
}
for ( int i = x - 1; i < n; i++) {
if (i == (x - 1))
noOfOnes = preCompute[i];
else
noOfOnes = preCompute[i] - preCompute[i - x];
if (maxOnes < noOfOnes)
maxOnes = noOfOnes;
}
int noOfZeroes = x - maxOnes;
return noOfZeroes;
}
public static void Main ()
{
int []a = {1, 0, 1, 0, 1};
int n = a.Length;
Console.WriteLine( minSwaps(a, n));
}
}
|
PHP
<?php
function minSwaps( $arr , $n )
{
$noOfOnes = 0;
for ( $i = 0; $i < $n ; $i ++)
{
if ( $arr [ $i ] == 1)
$noOfOnes ++;
}
$x = $noOfOnes ;
$maxOnes = PHP_INT_MIN;
$preCompute = array ();
if ( $arr [0] == 1)
$preCompute [0] = 1;
for ( $i = 1; $i < $n ; $i ++)
{
if ( $arr [ $i ] == 1)
{
$preCompute [ $i ] = $preCompute [ $i - 1] + 1;
}
else
$preCompute [ $i ] = $preCompute [ $i - 1];
}
for ( $i = $x - 1; $i < $n ; $i ++)
{
if ( $i == ( $x - 1))
$noOfOnes = $preCompute [ $i ];
else
$noOfOnes = $preCompute [ $i ] -
$preCompute [ $i - $x ];
if ( $maxOnes < $noOfOnes )
$maxOnes = $noOfOnes ;
}
$noOfZeroes = $x - $maxOnes ;
return $noOfZeroes ;
}
$a = array (1, 0, 1, 0, 10);
$n = count ( $a );
echo minSwaps( $a , $n );
?>
|
Javascript
<script>
function minSwaps(arr, n) {
let noOfOnes = 0;
for (let i = 0; i < n; i++) {
if (arr[i] == 1)
noOfOnes++;
}
let x = noOfOnes;
let maxOnes = Number.MIN_VALUE;
let preCompute = new Array(n);
preCompute.fill(0);
if (arr[0] == 1)
preCompute[0] = 1;
for (let i = 1; i < n; i++) {
if (arr[i] == 1) {
preCompute[i] = preCompute[i - 1] + 1;
} else
preCompute[i] = preCompute[i - 1];
}
for (let i = x - 1; i < n; i++) {
if (i == (x - 1))
noOfOnes = preCompute[i];
else
noOfOnes = preCompute[i] - preCompute[i - x];
if (maxOnes < noOfOnes)
maxOnes = noOfOnes;
}
let noOfZeroes = x - maxOnes;
return noOfZeroes;
}
let a = [1, 0, 1, 0, 1];
let n = a.length;
document.write( minSwaps(a, n));
</script>
|
Time Complexity: O(n)
Auxiliary Space: O(n)
Another efficient approach :
First count total number of 1’s in the array. Suppose this count is x, now find the subarray of length x of this array with maximum number of 1’s using the concept of window-sliding technique. Maintain a variable to find number of 1’s present in a subarray in O(1) extra space and for each sub array maintain maxOnes Variable and at last Return numberOfZeros (numberOfZeroes = x – maxOnes).
Implementation:
C++
#include <iostream>
#include <limits.h>
using namespace std;
int minSwaps( int arr[], int n)
{
int numberOfOnes = 0;
for ( int i = 0; i < n; i++) {
if (arr[i] == 1)
numberOfOnes++;
}
int x = numberOfOnes;
int count_ones = 0, maxOnes;
for ( int i = 0; i < x; i++){
if (arr[i] == 1)
count_ones++;
}
maxOnes = count_ones;
for ( int i = 1; i <= n-x; i++) {
if (arr[i-1] == 1)
count_ones--;
if (arr[i+x-1] == 1)
count_ones++;
if (maxOnes < count_ones)
maxOnes = count_ones;
}
int numberOfZeroes = x - maxOnes;
return numberOfZeroes;
}
int main() {
int a[] = {0, 0, 1, 0, 1, 1, 0, 0, 1};
int n = sizeof (a) / sizeof (a[0]);
cout << minSwaps(a, n);
return 0;
}
|
Java
public class GFG {
static int minSwaps( int arr[], int n)
{
int numberOfOnes = 0 ;
for ( int i = 0 ; i < n; i++) {
if (arr[i] == 1 )
numberOfOnes++;
}
int x = numberOfOnes;
int count_ones = 0 , maxOnes;
for ( int i = 0 ; i < x; i++){
if (arr[i] == 1 )
count_ones++;
}
maxOnes = count_ones;
for ( int i = 1 ; i <= n-x; i++) {
if (arr[i - 1 ] == 1 )
count_ones--;
if (arr[i + x - 1 ] == 1 )
count_ones++;
if (maxOnes < count_ones)
maxOnes = count_ones;
}
int numberOfZeroes = x - maxOnes;
return numberOfZeroes;
}
public static void main(String args[])
{
int a[] = new int []{ 0 , 0 , 1 , 0 ,
1 , 1 , 0 , 0 , 1 };
int n = a.length;
System.out.println(minSwaps(a, n));
}
}
|
Python3
def minSwaps(arr, n) :
numberOfOnes = 0
for i in range ( 0 , n) :
if (arr[i] = = 1 ) :
numberOfOnes = numberOfOnes + 1
x = numberOfOnes
count_ones = 0
maxOnes = 0
for i in range ( 0 , x) :
if (arr[i] = = 1 ) :
count_ones = count_ones + 1
maxOnes = count_ones
for i in range ( 1 , (n - x + 1 )) :
if (arr[i - 1 ] = = 1 ) :
count_ones = count_ones - 1
if (arr[i + x - 1 ] = = 1 ) :
count_ones = count_ones + 1
if (maxOnes < count_ones) :
maxOnes = count_ones
numberOfZeroes = x - maxOnes
return numberOfZeroes
a = [ 0 , 0 , 1 , 0 , 1 , 1 , 0 , 0 , 1 ]
n = 9
print (minSwaps(a, n))
|
C#
using System;
class GFG{
static int minSwaps( int []arr, int n)
{
int numberOfOnes = 0;
for ( int i = 0; i < n; i++) {
if (arr[i] == 1)
numberOfOnes++;
}
int x = numberOfOnes;
int count_ones = 0, maxOnes;
for ( int i = 0; i < x; i++){
if (arr[i] == 1)
count_ones++;
}
maxOnes = count_ones;
for ( int i = 1; i <= n-x; i++) {
if (arr[i - 1] == 1)
count_ones--;
if (arr[i + x - 1] == 1)
count_ones++;
if (maxOnes < count_ones)
maxOnes = count_ones;
}
int numberOfZeroes = x - maxOnes;
return numberOfZeroes;
}
static public void Main ()
{
int []a = {0, 0, 1, 0, 1, 1, 0, 0, 1};
int n = a.Length;
Console.WriteLine(minSwaps(a, n));
}
}
|
PHP
<?php
function minSwaps( $arr , $n )
{
$numberOfOnes = 0;
for ( $i = 0; $i < $n ; $i ++)
{
if ( $arr [ $i ] == 1)
$numberOfOnes ++;
}
$x = $numberOfOnes ;
$count_ones = 0;
$maxOnes ;
for ( $i = 0; $i < $x ; $i ++)
{
if ( $arr [ $i ] == 1)
$count_ones ++;
}
$maxOnes = $count_ones ;
for ( $i = 1; $i <= $n - $x ; $i ++)
{
if ( $arr [ $i - 1] === 1)
$count_ones --;
if ( $arr [ $i + $x - 1] === 1)
$count_ones ++;
if ( $maxOnes < $count_ones )
$maxOnes = $count_ones ;
}
$numberOfZeroes = $x - $maxOnes ;
return $numberOfZeroes ;
}
$a = array (0, 0, 1, 0, 1, 1, 0, 0, 1);
$n = 9;
echo minSwaps( $a , $n );
?>
|
Javascript
<script>
function minSwaps(arr, n)
{
let numberOfOnes = 0;
for (let i = 0; i < n; i++) {
if (arr[i] == 1)
numberOfOnes++;
}
let x = numberOfOnes;
let count_ones = 0, maxOnes;
for (let i = 0; i < x; i++){
if (arr[i] == 1)
count_ones++;
}
maxOnes = count_ones;
for (let i = 1; i <= n-x; i++) {
if (arr[i - 1] == 1)
count_ones--;
if (arr[i + x - 1] == 1)
count_ones++;
if (maxOnes < count_ones)
maxOnes = count_ones;
}
let numberOfZeroes = x - maxOnes;
return numberOfZeroes;
}
let a = [0, 0, 1, 0, 1, 1, 0, 0, 1];
let n = a.length;
document.write(minSwaps(a, n));
</script>
|
Time Complexity : O(n)
Auxiliary Space : O(1)
Thanks to Mr. Gera for suggesting this approach.
Sliding window Easy to understand version
Algorithm:
- Store the total no of ones in a variable say count. This will be the window size.
- Initialise a variable to store maximum no of ones out of all the sub arrays of size count and a variable to store count of ones in current window.
- Now iterate over the array and as soon as you hit the window size compare the no of ones in that window with the maximum count of ones in all the windows so far and update max count of ones if count of ones in the current window is more. If the first element of window is 1 then decrease the current count.
- Answer will be total count of ones – max count of ones out of all window.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
int minSwaps( int arr[], int n)
{
int totalCount = 0;
for ( int i = 0; i < n; i++)
totalCount += arr[i];
int currCount = 0;
int maxCount = 0;
int i = 0;
int j = 0;
while (j < n)
{
currCount += arr[j];
if ((j - i + 1) == totalCount)
{
maxCount = max(maxCount, currCount);
if (arr[i] == 1)
currCount--;
i++;
}
j++;
}
return totalCount - maxCount;
}
int main()
{
int a[] = {1, 0, 1, 0, 1, 1};
int n = sizeof (a) / sizeof (a[0]);
cout << minSwaps(a, n);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG{
static int minSwaps( int [] arr, int n)
{
int totalCount = 0 ;
int i;
for (i = 0 ; i < n; i++)
totalCount += arr[i];
int currCount = 0 ;
int maxCount = 0 ;
i = 0 ;
int j = 0 ;
while (j < n)
{
currCount += arr[j];
if ((j - i + 1 ) == totalCount)
{
maxCount = Math.max(maxCount, currCount);
if (arr[i] == 1 )
currCount--;
i++;
}
j++;
}
return totalCount - maxCount;
}
public static void main(String args[])
{
int [] a = { 1 , 0 , 1 , 0 , 1 , 1 };
int n = a.length;
System.out.println(minSwaps(a, n));
}
}
|
Python
def minSwaps(arr, n):
totalCount = 0
for i in range ( 0 ,n):
totalCount + = arr[i]
currCount = 0
maxCount = 0
i = 0
j = 0
while (j < n):
currCount + = arr[j]
if ((j - i + 1 ) = = totalCount):
maxCount = max (maxCount, currCount)
if (arr[i] = = 1 ):
currCount - = 1
i + = 1
j + = 1
return totalCount - maxCount
a = [ 1 , 0 , 1 , 0 , 1 , 1 ]
n = len (a)
print (minSwaps(a, n))
|
C#
using System;
class GFG{
static int minSwaps( int [] arr, int n)
{
int totalCount = 0;
int i;
for (i = 0; i < n; i++)
totalCount += arr[i];
int currCount = 0;
int maxCount = 0;
i = 0;
int j = 0;
while (j < n)
{
currCount += arr[j];
if ((j - i + 1) == totalCount)
{
maxCount = Math.Max(maxCount, currCount);
if (arr[i] == 1)
currCount--;
i++;
}
j++;
}
return totalCount - maxCount;
}
public static void Main()
{
int [] a = { 1, 0, 1, 0, 1, 1 };
int n = a.Length;
Console.WriteLine(minSwaps(a, n));
}
}
|
Javascript
<script>
function minSwaps(arr, n)
{
let totalCount = 0;
let i;
for (i = 0; i < n; i++)
totalCount += arr[i];
let currCount = 0;
let maxCount = 0;
i = 0;
let j = 0;
while (j < n)
{
currCount += arr[j];
if ((j - i + 1) == totalCount)
{
maxCount = Math.max(maxCount, currCount);
if (arr[i] == 1)
currCount--;
i++;
}
j++;
}
return totalCount - maxCount;
}
let a = [ 1, 0, 1, 0, 1, 1 ];
let n = a.length;
document.write(minSwaps(a, n));
</script>
|
Complexities:
- Time Complexities: O(n)
- Space Complexities: O(1)