Convert a Binary String to another by flipping prefixes minimum number of times
Last Updated :
17 Jan, 2022
Given two binary strings A and B of length N, the task is to convert the string A to B by repeatedly flipping a prefix of A, i.e. reverse the order of occurrence of bits in the chosen prefix. Print the number of flips required and the length of all prefixes.
Examples:
Input: A = “01”, B = “10”
Output:
3
1 2 1
Explanation:
Operation 1: Select the prefix of length 1 from the string A (= “01”). Flipping the prefix “0” modifies the string to “11”.
Operation 2: Select the prefix of length 2 from the string A (= “11”). Flipping the prefix “11” modifies the string to “00”.
Operation 3: Select the prefix of length 1 from the string A (= “00”). Flipping the prefix “0” to “1” modifies the string to “10”, which is the same as the string B.
Therefore, the total number of operations required is 3.
Input: A = “0”, B = “1”
Output:
1
1
Approach: The given problem can be solved by fixing the bits one-by-one. To fix the ith bit, when A[i] and B[i] are unequal, flip the prefix of length i followed by flipping the prefix of length 1. Now, flip the prefix of length i. These three operations do not change any other bits in A. Perform these operations at all indices where A[i] is unequal B[i]. Since 3 operations are used per bit, overall 3 * N operations will be used.
In order to minimize the number of operations, the above approach can be modified by fixing the bits one by one in reverse order. To fix the ith bit, either the prefix of length i is required to be flipped or the first bit, and then the prefix of length i is required to be flipped. But in reverse order, the previously fixed bits do not get flipped again by this procedure and at most 2 operations are needed per bit. Therefore, the minimum number of operations required is 2*N.
Below is the implementation of the above approach:
C++14
#include <bits/stdc++.h>
using namespace std;
void minOperations(string a, string b, int n)
{
vector< int > ops;
for ( int i = n - 1; i >= 0; i--) {
if (a[i] != b[i]) {
if (a[0] == b[i]) {
ops.push_back(1);
a[0] = '0' + !(a[0] - '0' );
}
reverse(a.begin(), a.begin() + i + 1);
for ( int j = 0; j <= i; j++) {
a[j] = '0' + !(a[j] - '0' );
}
ops.push_back(i + 1);
}
}
cout << ops.size() << "\n" ;
for ( int x : ops) {
cout << x << ' ' ;
}
}
int main()
{
string a = "10" , b = "01" ;
int N = a.size();
minOperations(a, b, N);
return 0;
}
|
Java
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG
{
static void minOperations(String s1, String s2, int n)
{
char a[] = s1.toCharArray();
char b[] = s2.toCharArray();
ArrayList<Integer> ops = new ArrayList<>();
for ( int i = n - 1 ; i >= 0 ; i--) {
if (a[i] != b[i]) {
if (a[ 0 ] == b[i]) {
ops.add( 1 );
a[ 0 ] = (a[ 0 ] == '0' ? '1' : '0' );
}
reverse(a, 0 , i);
for ( int j = 0 ; j <= i; j++) {
a[j] = (a[j] == '0' ? '1' : '0' );
}
ops.add(i + 1 );
}
}
System.out.println(ops.size());
for ( int x : ops) {
System.out.print(x + " " );
}
}
static void reverse( char a[], int start, int end)
{
while (start < end) {
char temp = a[start];
a[start] = a[end];
a[end] = temp;
start++;
end--;
}
}
public static void main(String[] args)
{
String a = "10" , b = "01" ;
int N = a.length();
minOperations(a, b, N);
}
}
|
Python3
def minOperations(a, b, n):
ops = []
a = list (a)
for i in range (n - 1 , - 1 , - 1 ):
if (a[i] ! = b[i]):
if (a[ 0 ] = = b[i]):
ops.append( 1 )
if ( ord (a[ 0 ]) - ord ( '0' )):
a[ 0 ] = chr ( ord ( '0' ) + ord ( '0' ))
else :
a[ 0 ] = chr ( ord ( '0' ) + ord ( '1' ))
a[:i + 1 ].reverse()
for j in range (i + 1 ):
if ( ord (a[j]) - ord ( '0' )):
a[j] = chr ( ord ( '0' ) + ord ( '0' ))
else :
a[j] = chr ( ord ( '0' ) + ord ( '1' ))
ops.append(i + 1 )
print ( len (ops))
for x in ops:
print (x, end = " " )
if __name__ = = "__main__" :
a = "10"
b = "01"
N = len (a)
minOperations(a, b, N)
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static void minOperations( string s1, string s2, int n)
{
char [] a = s1.ToCharArray();
char [] b = s2.ToCharArray();
List< int > ops = new List< int >();
for ( int i = n - 1; i >= 0; i--) {
if (a[i] != b[i]) {
if (a[0] == b[i]) {
ops.Add(1);
a[0] = (a[0] == '0' ? '1' : '0' );
}
reverse(a, 0, i);
for ( int j = 0; j <= i; j++) {
a[j] = (a[j] == '0' ? '1' : '0' );
}
ops.Add(i + 1);
}
}
Console.WriteLine(ops.Count);
foreach ( int x in ops) {
Console.Write(x + " " );
}
}
static void reverse( char [] a, int start, int end)
{
while (start < end) {
char temp = a[start];
a[start] = a[end];
a[end] = temp;
start++;
end--;
}
}
public static void Main()
{
string a = "10" , b = "01" ;
int N = a.Length;
minOperations(a, b, N);
}
}
|
Javascript
<script>
function minOperations(s1, s2, n) {
var a = s1.split( "" );
var b = s2.split( "" );
var ops = [];
for ( var i = n - 1; i >= 0; i--) {
if (a[i] !== b[i]) {
if (a[0] === b[i]) {
ops.push(1);
a[0] = a[0] === "0" ? "1" : "0" ;
}
reverse(a, 0, i);
for ( var j = 0; j <= i; j++) {
a[j] = a[j] === "0" ? "1" : "0" ;
}
ops.push(i + 1);
}
}
document.write(ops.length + "<br>" );
for (const x of ops) {
document.write(x + " " );
}
}
function reverse(a, start, end) {
while (start < end) {
var temp = a[start];
a[start] = a[end];
a[end] = temp;
start++;
end--;
}
}
var a = "10" , b = "01" ;
var N = a.length;
minOperations(a, b, N);
</script>
|
Time Complexity: O(N2)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...