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++
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
#define INF 1000000000
// Function to find the minimum cost
// required to swap every set bit with
// an unset bit
int minimumCost(string s)
{
int N = s.length();
// Stores the indices of set and
// unset bits of the string S
vector<int> A, B;
// Traverse the string S
for (int i = 0; i < N; i++) {
// Store the indices
if (s[i] == '1') {
A.push_back(i);
}
else {
B.push_back(i);
}
}
int n1 = A.size();
int n2 = B.size();
// Initialize a dp table of size
// n1*n2
int dp[n1 + 1][n2 + 1];
// Initialize all states to 0
memset(dp, 0, sizeof(dp));
// Set unreachable states to INF
for (int i = 1; i <= n1; i++) {
dp[i][0] = INF;
}
// Fill the dp Table according to
// the given recurrence relation
for (int i = 1; i <= n1; i++) {
for (int j = 1; j <= n2; j++) {
// Update the value of
// dp[i][j]
dp[i][j] = min(
dp[i][j - 1],
dp[i - 1][j - 1]
+ abs(A[i - 1] - B[j - 1]));
}
}
// Return the minimum cost
return dp[n1][n2];
}
// Driver Code
int main()
{
string S = "1010001";
cout << minimumCost(S);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
static final int INF = 1000000000;
// Function to find the minimum cost
// required to swap every set bit with
// an unset bit
static int minimumCost(String s)
{
int N = s.length();
// Stores the indices of set and
// unset bits of the String S
Vector<Integer> A = new Vector<Integer>();
Vector<Integer> B = new Vector<Integer>();
// Traverse the String S
for (int i = 0; i < N; i++) {
// Store the indices
if (s.charAt(i) == '1') {
A.add(i);
}
else {
B.add(i);
}
}
int n1 = A.size();
int n2 = B.size();
// Initialize a dp table of size
// n1*n2
int [][]dp = new int[n1 + 1][n2 + 1];
// Set unreachable states to INF
for (int i = 1; i <= n1; i++) {
dp[i][0] = INF;
}
// Fill the dp Table according to
// the given recurrence relation
for (int i = 1; i <= n1; i++) {
for (int j = 1; j <= n2; j++) {
// Update the value of
// dp[i][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 the minimum cost
return dp[n1][n2];
}
// Driver Code
public static void main(String[] args)
{
String S = "1010001";
System.out.print(minimumCost(S));
}
}
// This code is contributed by shikhasingrajput
Python3
# Python program for the above approach
INF = 1000000000
# Function to find the minimum cost
# required to swap every set bit with
# an unset bit
def minimumCost(s):
N = len(s)
# Stores the indices of set and
# unset bits of the string S
A = []
B = []
# Traverse the string S
for i in range(0, N):
# Store the indices
if (s[i] == "1"):
A.append(i)
else:
B.append(i)
n1 = len(A)
n2 = len(B)
# Initialize a dp table of size
# n1*n2
dp = [[0 for i in range(n2 + 1)] for j in range(n1 + 1)]
# Set unreachable states to INF
for i in range(1, n1 + 1):
dp[i][0] = INF
# Fill the dp Table according to
# the given recurrence relation
for i in range(1, n1 + 1):
for j in range(1, n2 + 1):
# Update the value of
# dp[i][j]
dp[i][j] = min(
dp[i][j - 1],
dp[i - 1][j - 1] + abs(A[i - 1] - B[j - 1])
)
# Return the minimum cost
return dp[n1][n2]
# Driver Code
S = "1010001"
print(minimumCost(S))
# This code is contributed by _saurabh_jaiswal.
C#
// C# program for the above approach
using System;
using System.Collections;
using System.Collections.Generic;
public class Program
{
// Function to find the minimum cost
// required to swap every set bit with
// an unset bit
static int minimumCost(string s)
{
int INF = 1000000000;
int N = s.Length;
// Stores the indices of set and
// unset bits of the string S
List<int> A = new List<int>();
List<int> B = new List<int>();
// Traverse the string S
for (int i = 0; i < N; i++) {
// Store the indices
if (s[i] == '1') {
A.Add(i);
}
else {
B.Add(i);
}
}
int n1 = A.Count;
int n2 = B.Count;
// Initialize a dp table of size
// n1*n2
int [,]dp = new int[n1 + 1,n2 + 1];
// Set unreachable states to INF
for (int i = 1; i <= n1; i++) {
dp[i,0] = INF;
}
// Fill the dp Table according to
// the given recurrence relation
for (int i = 1; i <= n1; i++) {
for (int j = 1; j <= n2; j++) {
// Update the value of
// dp[i][j]
dp[i,j] = Math.Min(
dp[i,j - 1],
dp[i - 1,j - 1]
+ Math.Abs(A[i - 1] - B[j - 1]));
}
}
// Return the minimum cost
return dp[n1,n2];
}
public static void Main()
{
string S = "1010001";
Console.Write(minimumCost(S));
}
}
// This code is contributed by rutvik_56.
JavaScript
<script>
// Javascript program for the above approach
let INF = 1000000000;
// Function to find the minimum cost
// required to swap every set bit with
// an unset bit
function minimumCost(s) {
let N = s.length;
// Stores the indices of set and
// unset bits of the string S
let A = [],
B = [];
// Traverse the string S
for (let i = 0; i < N; i++) {
// Store the indices
if (s[i] == "1") {
A.push(i);
} else {
B.push(i);
}
}
let n1 = A.length;
let n2 = B.length;
// Initialize a dp table of size
// n1*n2
let dp = new Array(n1 + 1).fill(0).map(() => new Array(n2 + 1).fill(0));
// Set unreachable states to INF
for (let i = 1; i <= n1; i++) {
dp[i][0] = INF;
}
// Fill the dp Table according to
// the given recurrence relation
for (let i = 1; i <= n1; i++) {
for (let j = 1; j <= n2; j++) {
// Update the value of
// dp[i][j]
dp[i][j] = Math.min(
dp[i][j - 1],
dp[i - 1][j - 1] + Math.abs(A[i - 1] - B[j - 1])
);
}
}
// Return the minimum cost
return dp[n1][n2];
}
// Driver Code
let S = "1010001";
document.write(minimumCost(S));
// This code is contributed by gfgking.
</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
// Function to find the minimum cost
// required to swap every set bit with
// an unset bit
int minimumCost(string s)
{
int n1 = 0, n2 = 0;
for (char c : s) {
if (c == '1') n1++;
else n2++;
}
// Initialize a dp table of size
// n1*n2
int dp[n1 + 1];
// Initialize all states to 0
memset(dp, 0, sizeof(dp));
// Set unreachable states to INF
for (int i = 1; i <= n1; i++) {
dp[i] = INF;
}
// Fill the dp Table according to
// the given recurrence relation
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 the minimum cost
return dp[n1];
}
// Driver Code
int main()
{
string S = "1010001";
cout << minimumCost(S);
return 0;
}
Java
import java.util.Arrays;
public class MinimumCost {
static int INF = 1000000000;
// Function to find the minimum cost
// required to swap every set bit with
// an unset bit
static int minimumCost(String s) {
int n1 = 0, n2 = 0;
for (char c : s.toCharArray()) {
if (c == '1') {
n1++;
} else {
n2++;
}
}
// Initialize a dp table of size
// n1*n2
int[] dp = new int[n1 + 1];
// Initialize all states to 0
Arrays.fill(dp, 0);
// Set unreachable states to INF
for (int i = 1; i <= n1; i++) {
dp[i] = INF;
}
// Fill the dp Table according to
// the given recurrence relation
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 the minimum cost
return dp[n1];
}
// Driver Code
public static void main(String[] args) {
String S = "1010001";
System.out.println(minimumCost(S));
}
}
Python
INF = 1000000000
# Function to find the minimum cost
# required to swap every set bit with an unset bit
def minimumCost(s):
n1 = s.count('1')
n2 = len(s) - n1
# Initialize a dp table of size n1*n2
dp = [0]*(n1 + 1)
# Set unreachable states to INF
for i in range(1, n1 + 1):
dp[i] = INF
# Fill the dp Table according
# to the given recurrence relation
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 the minimum cost
return dp[n1]
# Driver Code
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)); // Output: 3
Time Complexity: O(N^2)
Auxiliary Space: O(N)
Similar Reads
Maximize sum of assigned weights by flipping at most K bits in given Binary String
Given a binary string str of length N and an integer K, the task is to find the maximum possible sum of assigned weights that can be obtained by flipping at most K bits in the given binary string. The weight assigned to the characters of this string are as follows: If a character is '0', then the we
13 min read
Minimize hamming distance in Binary String by setting only one K size substring bits
Given two binary strings S and T of length N and a positive integer K. Initially, all characters of T are '0'. The task is to find the minimum Hamming distance after choosing a substring of size K and making all elements of string T as '1' only once. Examples: Input: S = "101", K = 2Output: 1Explana
7 min read
Maximum number of set bits count in a K-size substring of a Binary String
Given a binary string S of size N and an integer K. The task is to find the maximum number of set bit appears in a substring of size K. Examples: Input: S = "100111010", K = 3 Output: 3 Explanation: The substring "111" contains 3 set bits. Input:S = "0000000", K = 4 Output: 0 Explanation: S doesn't
10 min read
Maximize count of 0s in left and 1s in right substring by splitting given Binary string
Given a binary string str, the task is to split the given binary string at any index into two non-empty substrings such that the sum of counts of 0s in the left substring and 1s in the right substring is maximum. Print the sum of such 0s and 1s in the end.Examples: Input: str = "0011110011" Output:
6 min read
Maximize sum by splitting given binary strings based on given conditions
Given two binary strings str1 and str2 each of length N, the task is to split the strings in such a way that the sum is maximum with given conditions. Split both strings at the same position into equal length substrings.If both the substrings have only 0's then the value of that substring to be adde
7 min read
Minimize cost of flipping or swaps to make a Binary String balanced
Given a binary string S of size N(where N is even), the task is to find the minimum cost of making the given binary string balanced by flipping one of the adjacent different characters at the cost of 1 unit or swap the characters at indices i and j such that (i < j) at the cost of (j - i) unit. I
6 min read
Minimize flipping of bits in given Binary string to make count of 10 equal to 01
Given binary string str, the task is to choose any index and change into 0 or 1, and do this in minimum steps such that the count of substring 01 is equal to 10. Examples: Input: str = "01101"Output: 01100Explanation: 01 as a substring repeat 2 times in a string, 10 as a substring repeat 1 times in
5 min read
Minimize count of 0s in Binary String by changing K-size substring to 1s at most Q times
Given a binary string S having N characters and two integers K and Q, the task is to find the minimum number of remaining zeroes after at most Q operations, such that in each operation, choose any substring of size at most K and change all its elements to 1. Example: Input: S = 000111, K = 2, Q = 1O
15+ min read
Count of setbits in bitwise OR of all K length substrings of given Binary String
Given a binary string str of length N, the task is to find the number of setbits in the bitwise OR of all the K length substrings of string str. Examples: Input: N = 4, K = 3, str = "1111"Output: 3Explanation: All 3-sized substrings of S are:"111" and "111". The OR of these strings is "111". Therefo
8 min read
Number of Binary Strings of length N with K adjacent Set Bits
Given n and k . The task is to find the number of binary strings of length n out of 2n such that they satisfy f(bit string) = k. Where, f(x) = Number of times a set bit is adjacent to another set bit in a binary string x.For Example:f(011101101) = 3f(010100000) = 0f(111111111) = 8Examples: Input : n
15+ min read