Minimize cost of swapping set bits with unset bits in a given Binary string
Last Updated :
15 May, 2023
Given a binary string S of size N, the task is to find the minimum cost by swapping every set bit with an unset bit such that the cost of swapping pairs of bits at indices i and j is abs(j – i).
Note: A swapped bit can’t be swapped twice and the count of set bit in the given binary string is at most N/2.
Examples:
Input: S = “1010001”
Output: 3
Explanation:
Following the swapping of characters required:
- Swap characters at indices (0, 1) modifies the string to “0110001” and the cost of this operation is |1 – 0| = 1.
- Swap characters at indices (2, 3) modifies the string to “0101001” and the cost of this operation is |2 – 1| = 1.
- Swap characters at indices (6, 7) modifies the string to “0101010” and the cost of this operation is |7 – 6| = 1.
After the above operations, all the set bits is replaced with unset bits and the total cost of operations is 1 + 1 + 1 = 3.
Input: S = “1100”
Output: 4
Approach: The given problem can be solved using Dynamic Programming by storing the indices of set and unset bits in two auxiliary arrays, say A[] and B[], and then find the sum of the difference between array elements A[] with any element of the array B[]. Follow the steps below to solve the given problem:
- Initialize two arrays, say A[] and B[], and store the indices of set and unset bits in it.
- Initialize a 2D array, dp[][] of dimensions K*(N – K) where K is the count of set bit in S such thatdp[i][j] stores the minimum cost of swapping the ith array element A[] with the jth array element B[].
- Now, for each state there are two choices:
- Swap the ith array element A[] till the (j – 1)th array element B[] as dp[i][j] = dp[i][j – 1].
- Swap the (i – 1)th array element A[] till the (j – 1)th array element B[] and the ith array element A[] with jth array element B[] and this state can be calculated as dp[i][j] = dp[i – 1][j – 1] + abs(A[i] – B[i]).
- Now, choose the minimum of the above two choices to find the current state as:
dp[i][j] = min(dp[i][j-1], dp[i-1][j-1] + abs(A[i] – B[j]))
- After completing the above steps, print the value of dp[K][N – K] as the resultant minimum number of operations.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define INF 1000000000
int minimumCost(string s)
{
int N = s.length();
vector< int > A, B;
for ( int i = 0; i < N; i++) {
if (s[i] == '1' ) {
A.push_back(i);
}
else {
B.push_back(i);
}
}
int n1 = A.size();
int n2 = B.size();
int dp[n1 + 1][n2 + 1];
memset (dp, 0, sizeof (dp));
for ( int i = 1; i <= n1; i++) {
dp[i][0] = INF;
}
for ( int i = 1; i <= n1; i++) {
for ( int j = 1; j <= n2; j++) {
dp[i][j] = min(
dp[i][j - 1],
dp[i - 1][j - 1]
+ abs (A[i - 1] - B[j - 1]));
}
}
return dp[n1][n2];
}
int main()
{
string S = "1010001" ;
cout << minimumCost(S);
return 0;
}
|
Java
import java.util.*;
class GFG{
static final int INF = 1000000000 ;
static int minimumCost(String s)
{
int N = s.length();
Vector<Integer> A = new Vector<Integer>();
Vector<Integer> B = new Vector<Integer>();
for ( int i = 0 ; i < N; i++) {
if (s.charAt(i) == '1' ) {
A.add(i);
}
else {
B.add(i);
}
}
int n1 = A.size();
int n2 = B.size();
int [][]dp = new int [n1 + 1 ][n2 + 1 ];
for ( int i = 1 ; i <= n1; i++) {
dp[i][ 0 ] = INF;
}
for ( int i = 1 ; i <= n1; i++) {
for ( int j = 1 ; j <= n2; j++) {
dp[i][j] = Math.min(
dp[i][j - 1 ],
dp[i - 1 ][j - 1 ]
+ Math.abs(A.get(i - 1 ) - B.get(j - 1 )));
}
}
return dp[n1][n2];
}
public static void main(String[] args)
{
String S = "1010001" ;
System.out.print(minimumCost(S));
}
}
|
Python3
INF = 1000000000
def minimumCost(s):
N = len (s)
A = []
B = []
for i in range ( 0 , N):
if (s[i] = = "1" ):
A.append(i)
else :
B.append(i)
n1 = len (A)
n2 = len (B)
dp = [[ 0 for i in range (n2 + 1 )] for j in range (n1 + 1 )]
for i in range ( 1 , n1 + 1 ):
dp[i][ 0 ] = INF
for i in range ( 1 , n1 + 1 ):
for j in range ( 1 , n2 + 1 ):
dp[i][j] = min (
dp[i][j - 1 ],
dp[i - 1 ][j - 1 ] + abs (A[i - 1 ] - B[j - 1 ])
)
return dp[n1][n2]
S = "1010001"
print (minimumCost(S))
|
C#
using System;
using System.Collections;
using System.Collections.Generic;
public class Program
{
static int minimumCost( string s)
{
int INF = 1000000000;
int N = s.Length;
List< int > A = new List< int >();
List< int > B = new List< int >();
for ( int i = 0; i < N; i++) {
if (s[i] == '1' ) {
A.Add(i);
}
else {
B.Add(i);
}
}
int n1 = A.Count;
int n2 = B.Count;
int [,]dp = new int [n1 + 1,n2 + 1];
for ( int i = 1; i <= n1; i++) {
dp[i,0] = INF;
}
for ( int i = 1; i <= n1; i++) {
for ( int j = 1; j <= n2; j++) {
dp[i,j] = Math.Min(
dp[i,j - 1],
dp[i - 1,j - 1]
+ Math.Abs(A[i - 1] - B[j - 1]));
}
}
return dp[n1,n2];
}
public static void Main()
{
string S = "1010001" ;
Console.Write(minimumCost(S));
}
}
|
Javascript
<script>
let INF = 1000000000;
function minimumCost(s) {
let N = s.length;
let A = [],
B = [];
for (let i = 0; i < N; i++) {
if (s[i] == "1" ) {
A.push(i);
} else {
B.push(i);
}
}
let n1 = A.length;
let n2 = B.length;
let dp = new Array(n1 + 1).fill(0).map(() => new Array(n2 + 1).fill(0));
for (let i = 1; i <= n1; i++) {
dp[i][0] = INF;
}
for (let i = 1; i <= n1; i++) {
for (let j = 1; j <= n2; j++) {
dp[i][j] = Math.min(
dp[i][j - 1],
dp[i - 1][j - 1] + Math.abs(A[i - 1] - B[j - 1])
);
}
}
return dp[n1][n2];
}
let S = "1010001" ;
document.write(minimumCost(S));
</script>
|
Time Complexity: O(K*(N – K)) where K is the count of set bit in S.
Auxiliary Space: O(K*(N – K))
Efficient approach : Space optimization
In previous approach the current value dp[i][j] is only depend upon the current and previous row values of DP. So to optimize the space complexity we use a single 1D array to store the computations.
Implementation steps:
- Create a 1D vector dp of size n+1 and initialize it with 0.
- Set a base case by initializing the values of DP .
- Now iterate over subproblems by the help of nested loop and get the current value from previous computations.
- At last return and print the final answer stored in dp[n].
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
#define INF 1000000000
int minimumCost(string s)
{
int n1 = 0, n2 = 0;
for ( char c : s) {
if (c == '1' ) n1++;
else n2++;
}
int dp[n1 + 1];
memset (dp, 0, sizeof (dp));
for ( int i = 1; i <= n1; i++) {
dp[i] = INF;
}
for ( char c : s) {
for ( int i = n1; i >= 1; i--) {
if (c == '0' ) dp[i] = min(dp[i], dp[i - 1] + n2 - i + 1);
else dp[i] = min(dp[i], dp[i - 1] + i - 1);
}
}
return dp[n1];
}
int main()
{
string S = "1010001" ;
cout << minimumCost(S);
return 0;
}
|
Java
import java.util.Arrays;
public class MinimumCost {
static int INF = 1000000000 ;
static int minimumCost(String s) {
int n1 = 0 , n2 = 0 ;
for ( char c : s.toCharArray()) {
if (c == '1' ) {
n1++;
} else {
n2++;
}
}
int [] dp = new int [n1 + 1 ];
Arrays.fill(dp, 0 );
for ( int i = 1 ; i <= n1; i++) {
dp[i] = INF;
}
for ( char c : s.toCharArray()) {
for ( int i = n1; i >= 1 ; i--) {
if (c == '0' ) {
dp[i] = Math.min(dp[i], dp[i - 1 ] + n2 - i + 1 );
} else {
dp[i] = Math.min(dp[i], dp[i - 1 ] + i - 1 );
}
}
}
return dp[n1];
}
public static void main(String[] args) {
String S = "1010001" ;
System.out.println(minimumCost(S));
}
}
|
Python
INF = 1000000000
def minimumCost(s):
n1 = s.count( '1' )
n2 = len (s) - n1
dp = [ 0 ] * (n1 + 1 )
for i in range ( 1 , n1 + 1 ):
dp[i] = INF
for c in s:
for i in range (n1, 0 , - 1 ):
if c = = '0' :
dp[i] = min (dp[i], dp[i - 1 ] + n2 - i + 1 )
else :
dp[i] = min (dp[i], dp[i - 1 ] + i - 1 )
return dp[n1]
if __name__ = = "__main__" :
S = "1010001"
print (minimumCost(S))
|
C#
using System;
namespace MinimumCostToSwapBits
{
class Program
{
static int INF = 1000000000;
static int MinimumCost( string s)
{
int n1 = 0, n2 = 0;
foreach ( char c in s)
{
if (c == '1' ) n1++;
else n2++;
}
int [] dp = new int [n1 + 1];
Array.Fill(dp, 0);
for ( int i = 1; i <= n1; i++)
{
dp[i] = INF;
}
foreach ( char c in s)
{
for ( int i = n1; i >= 1; i--)
{
if (c == '0' ) dp[i] = Math.Min(dp[i], dp[i - 1] + n2 - i + 1);
else dp[i] = Math.Min(dp[i], dp[i - 1] + i - 1);
}
}
return dp[n1];
}
static void Main( string [] args)
{
string S = "1010001" ;
Console.WriteLine(MinimumCost(S));
}
}
}
|
Javascript
function minimumCost(s) {
const INF = 1000000000;
let n1 = 0, n2 = 0;
for (let i = 0; i < s.length; i++) {
if (s.charAt(i) == '1' ) n1++;
else n2++;
}
const dp = new Array(n1 + 1).fill(0);
for (let i = 1; i <= n1; i++) {
dp[i] = INF;
}
for (let i = 0; i < s.length; i++) {
const c = s.charAt(i);
for (let j = n1; j >= 1; j--) {
if (c == '0' ) dp[j] = Math.min(dp[j], dp[j - 1] + n2 - j + 1);
else dp[j] = Math.min(dp[j], dp[j - 1] + j - 1);
}
}
return dp[n1];
}
const S = "1010001" ;
console.log(minimumCost(S));
|
Time Complexity: O(N^2)
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...