Minimize cost to sort Binary String by swapping pairs or reversing prefix at most once
Last Updated :
10 Jan, 2023
Given binary string S of length N, the task is to minimize cost to sort the binary string using the following operations:
- Operation-1: Take any two indices i and j such that 0 ? i, j < N and swap Si and Sj. This operation is performed any number of times. Its cost is 1.
- Operation-2: Take any prefix of length i, where 1 ? i, j ? N, and reverse this prefix of the binary string. It can be performed at most once and its cost is 0.
Examples:
Input: S = “10100”
Output: 1
?Explanation: Perform an operation 1 by choosing i = 1 and j=2.
So 10100 becomes 11000, and cost is 1.
Then, perform an operation 2, by choosing i = 5,
which means reverse the entire string, and so from 1100, we get 00011.
This operation cost is 0.
So total cost is 0 + 1 = 1.
Input: S = “101”
?Output: 0
Approach: The problem can be solved based on the following observation:
- Note that the operations can always be reordered so that the prefix reverse operation is performed first – if any swaps are made before the reverse operation, these swaps can be performed (on maybe different positions) after reversing the prefix.
- So, fix length of the prefix to reverse, say i(0 ? i ? N) and calculate the minimum number of swaps required to sort the string now.
Based on the above observations, this idea can be formed:
As, cost of operation 2 is 0, just sort the binary string with either 0s in first or 1s in first and which ever costs less would be the answer.
Follow the steps mentioned below to implement the above idea:
- Say there are x 0s and y 1s. So all the first x characters will be 0 and the last y characters will be 1.
- If any of the first x characters is already a zero, it is in place and nothing needs to be done.
- If any of the first x characters is a one, it needs to be swapped out with a zero. This can be done in exactly one move since each one among the first x characters will correspond to a one among the last y characters.
- Create a prefix array to store the number of 0s till ith index.
- For each index check the value of (pref[n]-pref[n-ones+i]+pref[i]) where ones is the number of 1s in the string. The minimum among these is the answer.
Below is the implementation of the above approach.
C++
#include "bits/stdc++.h"
using namespace std;
int numOfOperation(string s, int n)
{
vector< int > pref(n + 1);
for ( int i = 0; i < n; i++) {
pref[i + 1] = pref[i] + (s[i] == '0' );
}
int ans = n;
int ones = n - pref[n];
for ( int i = 0; i <= ones; i++) {
ans = min(ans, pref[n] - pref[n - ones + i] + pref[i]);
}
return ans;
}
int main()
{
string S = "10100" ;
int N = ( int )S.size();
cout << numOfOperation(S, N);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
public static int numOfOperation(String s, int n)
{
int pref[] = new int [n + 1 ];
for ( int i = 0 ; i < n; i++) {
pref[i + 1 ]
= pref[i] + (s.charAt(i) == '0' ? 1 : 0 );
}
int ans = n;
int ones = n - pref[n];
for ( int i = 0 ; i <= ones; i++) {
ans = Math.min(ans, pref[n] - pref[n - ones + i]
+ pref[i]);
}
return ans;
}
public static void main(String[] args)
{
String S = "10100" ;
int N = S.length();
System.out.println(numOfOperation(S, N));
}
}
|
Python3
def numOfOperations(s, n):
pref = [ 0 ] * (n + 1 )
for i in range (n):
if (s[i] = = '0' ):
temp = 1
else :
temp = 0
pref[i + 1 ] = pref[i] + temp
ans = n
ones = n - pref[n]
for i in range (ones + 1 ):
ans = min (ans, pref[n] - pref[n - ones + i] + pref[i])
return ans
S = "10100"
N = len (S)
print (numOfOperations(S, N))
|
C#
using System;
public class GFG {
public static int numOfOperation( string s, int n)
{
int []pref = new int [n + 1];
for ( int i = 0; i < n; i++) {
pref[i + 1] = pref[i] + (s[i] == '0' ? 1 : 0);
}
int ans = n;
int ones = n - pref[n];
for ( int i = 0; i <= ones; i++) {
ans = Math.Min(ans, pref[n] - pref[n - ones + i]
+ pref[i]);
}
return ans;
}
public static void Main( string [] args)
{
string S = "10100" ;
int N = S.Length;
Console.WriteLine(numOfOperation(S, N));
}
}
|
Javascript
<script>
function numOfOperations(s, n){
let pref = new Array(n + 1);
for (let i = 0; i < n; i++)
pref[i] = 0;
for (let i = 0; i < n; i++){
if (s[i] == '0' )
temp = 1;
else
temp = 0;
pref[i+1] = pref[i] + temp;
}
let ans = n
let ones = n-pref[n]
for (i = 0; i < ones + 1; i++)
ans = Math.min(ans, pref[n] - pref[n-ones+i] + pref[i])
return ans;
}
let S = "10100" ;
let N = S.length;
document.write(numOfOperations(S, N));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N), space of temporary vector used.
Share your thoughts in the comments
Please Login to comment...