Minimum Swaps required to group all 1's together
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 with 4 will
give arr[] = [1, 1, 1, 0, 0]
Input: arr[] = [1, 1, 0, 1, 0, 1, 1]
Output: 2
Explanation: Only 2 swap is required to group all 1's together. Swapping index 0 with 2 and
1 with 4 will give arr[] = [0, 0, 1, 1, 1, 1, 1]Input: arr[] = [0, 0, 0]
Output: -1
Explanation: No 1s are present in the array, so return -1.
Table of Content
[Naive Approach] - Using Nested loops - O(n^2) Time and O(n) Space
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 with maximum number of 1’s. And minimum swaps required will be the number of 0’s in this subarray of length x.
#include <bits/stdc++.h>
using namespace std;
int minSwaps(vector<int> &arr)
{
// Count 1s in the given array
int n = arr.size();
int countone = 0;
for (int i = 0; i < n; i++)
{
if (arr[i])
countone++;
}
if (countone == 0)
return -1;
// Consider every subarray of size equals
// countone
int minswap = INT_MAX;
for (int i = 0; i < n - countone; i++)
{
int one = 0;
for (int j = i; j < (i + countone); j++)
{
if (arr[j])
one++;
}
minswap = min(minswap, (countone - one));
}
return minswap;
}
int main()
{
vector<int> a = {1, 0, 1, 0, 1};
cout << minSwaps(a);
return 0;
}
import java.util.*;
public class GfG {
static int minSwaps(int[] arr)
{
// Count the number of 1s in the array
int countOne = 0;
int n = arr.length;
for (int num : arr) {
if (num == 1)
countOne++;
}
if (countOne == 0)
return 0;
// Iterate over possible windows of size
// equals to countones
int minSwap = Integer.MAX_VALUE;
for (int i = 0; i <= n - countOne; i++) {
int oneCount = 0;
for (int j = i; j < i + countOne; j++) {
if (arr[j] == 1)
oneCount++;
}
minSwap
= Math.min(minSwap, countOne - oneCount);
}
return minSwap;
}
public static void main(String[] args)
{
int[] arr = { 1, 0, 1, 0, 1 };
System.out.println(minSwaps(arr));
}
}
def minSwaps(arr):
# Count number of 1s in the array
n = len(arr)
count_one = arr.count(1)
if count_one == 0:
return -1
min_swap = float('inf')
# Iterate over possible windows of size
# equals to countones
for i in range(n - count_one + 1):
one_count = sum(arr[i:i + count_one])
min_swap = min(min_swap, count_one - one_count)
return min_swap
# Driver code
arr = [1, 0, 1, 0, 1]
print(minSwaps(arr))
using System;
using System.Linq;
public class GfG {
static int MinSwaps(int[] arr)
{
// Count the number of 1s in the array
int countOne = 0;
int n = arr.Length;
foreach (int num in arr) {
if (num == 1)
countOne++;
}
if (countOne == 0)
return 0;
// Iterate over possible windows of size
// equals to countones
int minSwap = int.MaxValue;
for (int i = 0; i <= n - countOne; i++) {
int oneCount = 0;
for (int j = i; j < i + countOne; j++) {
if (arr[j] == 1)
oneCount++;
}
minSwap = Math.Min(minSwap, countOne - oneCount);
}
return minSwap;
}
public static void Main(string[] args)
{
int[] arr = { 1, 0, 1, 0, 1 };
Console.WriteLine(MinSwaps(arr));
}
}
function minSwaps(arr) {
// Count number of 1s in the array
const n = arr.length;
const count_one = arr.filter(x => x === 1).length;
if (count_one === 0) {
return -1;
}
let min_swap = Infinity;
// Iterate over possible windows of size
// equals to countones
for (let i = 0; i <= n - count_one; i++) {
const one_count = arr.slice(i, i + count_one).reduce((a, b) => a + b, 0);
min_swap = Math.min(min_swap, count_one - one_count);
}
return min_swap;
}
// Driver code
const arr = [1, 0, 1, 0, 1];
console.log(minSwaps(arr));
Output
1
[Expected Approach] - Maintaining Window K(count of 1) - O(n) Time and O(1) Space
This is mainly an optimization over the above approach. Count the total number of 1s (
x) in the array, then find a subarray of lengthxwith the maximum 1s using a sliding count. Track the maximum 1s in any such subarray and returnx - maxOnesas the minimum swaps needed.
#include <bits/stdc++.h>
using namespace std;
// Function to find minimum swaps
// to group all 1's together
int minSwaps(vector<int> &arr)
{
int n = arr.size();
int numberOfOnes = 0;
// find total number of all 1's in the array
for (int i = 0; i < n; i++)
{
if (arr[i] == 1)
numberOfOnes++;
}
if (numberOfOnes == 0)
return -1;
// length of subarray to check for
int x = numberOfOnes;
int count_ones = 0, maxOnes;
// Find 1's for first subarray of length x
for (int i = 0; i < x; i++)
{
if (arr[i] == 1)
count_ones++;
}
maxOnes = count_ones;
// using sliding window technique to find
// max number of ones in subarray of length x
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;
}
// calculate number of zeros in subarray
// of length x with maximum number of 1's
int numberOfZeroes = x - maxOnes;
return numberOfZeroes;
}
// Driver Code
int main()
{
vector<int> a = {0, 0, 1, 0, 1, 1, 0, 0, 1};
cout << minSwaps(a);
return 0;
}
public class GfG {
static int minSwaps(int arr[])
{
int numberOfOnes = 0;
int n = arr.length;
// find total number of all 1's
// in the array
for (int i = 0; i < n; i++) {
if (arr[i] == 1)
numberOfOnes++;
}
if (numberOfOnes == 0)
return -1;
// length of subarray to check for
int x = numberOfOnes;
int count_ones = 0, maxOnes;
// Find 1's for first subarray
// of length x
for (int i = 0; i < x; i++) {
if (arr[i] == 1)
count_ones++;
}
maxOnes = count_ones;
// using sliding window technique
// to find max number of ones in
// subarray of length x
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;
}
// calculate number of zeros in
// subarray of length x with
// maximum number of 1's
int numberOfZeroes = x - maxOnes;
return numberOfZeroes;
}
// Driver code
public static void main(String args[])
{
int a[] = new int[] { 0, 0, 1, 0, 1, 1, 0, 0, 1 };
System.out.println(minSwaps(a));
}
}
// This code is contributed by Sam007
def minSwaps(arr):
numberOfOnes = 0
n = len(arr)
# find total number of
# all 1's in the array
for i in range(0, n):
if (arr[i] == 1):
numberOfOnes = numberOfOnes + 1
if (numberOfOnes == 0):
return -1
# length of subarray
# to check for
x = numberOfOnes
count_ones = 0
maxOnes = 0
# Find 1's for first
# subarray of length x
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
# calculate number of
# zeros in subarray
# of length x with
# maximum number of 1's
numberOfZeroes = x - maxOnes
return numberOfZeroes
# Driver Code
a = [0, 0, 1, 0, 1, 1, 0, 0, 1]
print(minSwaps(a))
using System;
class GfG {
static int minSwaps(int[] arr)
{
int n = arr.Length;
int numberOfOnes = 0;
// find total number of all 1's in the array
for (int i = 0; i < n; i++) {
if (arr[i] == 1)
numberOfOnes++;
}
if (numberOfOnes == 0)
return -1;
// length of subarray to check for
int x = numberOfOnes;
int count_ones = 0, maxOnes;
// Find 1's for first subarray of length x
for (int i = 0; i < x; i++) {
if (arr[i] == 1)
count_ones++;
}
maxOnes = count_ones;
// using sliding window technique to find
// max number of ones in subarray of length x
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;
}
// calculate number of zeros in subarray
// of length x with maximum number of 1's
int numberOfZeroes = x - maxOnes;
return numberOfZeroes;
}
// Driver Code
static public void Main()
{
int[] a = { 0, 0, 1, 0, 1, 1, 0, 0, 1 };
Console.WriteLine(minSwaps(a));
}
}
function minSwaps(arr)
{
let n = arr.length;
let numberOfOnes = 0;
// find total number of all 1's in the array
for (let i = 0; i < n; i++) {
if (arr[i] == 1)
numberOfOnes++;
}
if (numberOfOnes == 0)
return -1;
// length of subarray to check for
let x = numberOfOnes;
let count_ones = 0, maxOnes;
// Find 1's for first subarray of length x
for (let i = 0; i < x; i++) {
if (arr[i] == 1)
count_ones++;
}
maxOnes = count_ones;
// using sliding window technique to find
// max number of ones in subarray of length x
for (let i = 1; i <= n - x; i++) {
// first remove leading element and check
// if it is equal to 1 then decrement the
// value of count_ones by 1
if (arr[i - 1] == 1)
count_ones--;
if (arr[i + x - 1] == 1)
count_ones++;
if (maxOnes < count_ones)
maxOnes = count_ones;
}
// calculate number of zeros in subarray
// of length x with maximum number of 1's
let numberOfZeroes = x - maxOnes;
return numberOfZeroes;
}
let a = [ 0, 0, 1, 0, 1, 1, 0, 0, 1 ];
console.log(minSwaps(a));
Output
1