Given two binary strings A and B of length N, the task is to convert the string from A to string B by repeatedly flipping all the bits of a prefix of A, i.e. convert all the 0s in the prefix to 1s and vice-versa and print the minimum number of prefix flips required and the length of respective prefixes.
Examples:
Input: A = “001”, B = “000”
Output:
2
3 2
Explanation:
Flipping the prefix “001” modifies the string to “110”.
Flipping the prefix “11” modifies the string to “000”.Input: A = “1000”, B = “1011”
Output:
2
4 2
Explanation:
Flipping the prefix “1000” modifies the string to “0111”.
Flipping the prefix “01” modifies the string to “1011”.
Naive Approach: The simplest approach is to traverse the string A in reverse and for every ith character obtained such that A[i] is not equal to B[i], flip the characters present in A from indices [0, i] and increment the number of operations by 1. After complete traversal of the string, print the count of operations and the prefix length chosen in each operation.
Time Complexity: O(N2)
Auxiliary Space: O(N)
Efficient Approach: The idea is to fix one bit at a time by traversing the string A in reverse. Maintain a boolean variable, say invert, initially set to false, to denote whether the current bits in A are flipped or not. While traversing, perform the following:
- If the iᵗʰ bit in A is not equal to the iᵗʰ bit in B and invert is false, then increment the count of operations and set invert to true.
- Otherwise, if the iᵗʰ bit in A is equal to the iᵗʰ bit in B and invert is true, then increment the count of operations and set invert to false.
Follow the steps below to solve the problem:
- Initialize a boolean variable, say invert as false, to denote whether the bits in A are flipped or not.
- Initialize an empty array, say res, to store the prefix length in each operation.
-
Iterate in the range [N – 1, 0] using the variable i and perform the following steps:
- If A[i] != B[i] and invert is false, then the current bit is required to be flipped. Therefore. insert (i + 1) into the array res and update invert to true.
- Otherwise, check if A[i] == B[i] and invert is true, then insert (i + 1) to res, and update invert to false.
- Print the size of the array res as the number of operations required to make the two strings equal.
- Then, print the values stored in res to denote the prefix length in each operation.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Function to count flips required // to make strings A and B equal void findOperations(string A,
string B, int N)
{ // Stores the count of the
// number of operations
int operations = 0;
// Stores the length of
// the chosen prefixes
vector< int > ops;
// Stores if operations are
// performed even or odd times
bool invert = false ;
// Traverse the given string
for ( int i = N - 1; i >= 0; i--) {
// If current characters in
// the two strings are unequal
if (A[i] != B[i]) {
// If A[i] is not flipped
if (!invert) {
// Increment count
// of operations
operations++;
// Insert the length of
// the chosen prefix
ops.push_back(i + 1);
// Update invert to true
invert = true ;
}
}
else {
// If A[i] is flipped
if (invert) {
// Increment count
// of operations
operations++;
// Insert length of
// the chosen prefix
ops.push_back(i + 1);
// Update invert to false
invert = false ;
}
}
}
// Print the number of
// operations required
cout << operations << endl;
// Print the chosen prefix
// length in each operation
if (operations != 0) {
for ( auto x : ops)
cout << x << " " ;
}
} // Driver Code int main()
{ // Given binary strings
string A = "001" , B = "000" ;
int N = A.size();
findOperations(A, B, N);
return 0;
} |
// Java program for the above approach import java.util.*;
class GFG{
// Function to count flips required // to make Strings A and B equal static void findOperations(String A,
String B, int N)
{ // Stores the count of the
// number of operations
int operations = 0 ;
// Stores the length of
// the chosen prefixes
Vector<Integer> ops = new Vector<>();
// Stores if operations are
// performed even or odd times
boolean invert = false ;
// Traverse the given String
for ( int i = N - 1 ; i >= 0 ; i--) {
// If current characters in
// the two Strings are unequal
if (A.charAt(i) != B.charAt(i)) {
// If A[i] is not flipped
if (!invert) {
// Increment count
// of operations
operations++;
// Insert the length of
// the chosen prefix
ops.add(i + 1 );
// Update invert to true
invert = true ;
}
}
else {
// If A[i] is flipped
if (invert) {
// Increment count
// of operations
operations++;
// Insert length of
// the chosen prefix
ops.add(i + 1 );
// Update invert to false
invert = false ;
}
}
}
// Print the number of
// operations required
System.out.print(operations + "\n" );
// Print the chosen prefix
// length in each operation
if (operations != 0 ) {
for ( int x : ops)
System.out.print(x+ " " );
}
} // Driver Code public static void main(String[] args)
{ // Given binary Strings
String A = "001" , B = "000" ;
int N = A.length();
findOperations(A, B, N);
} } // This code is contributed by Amit Katiyar |
# Python program for the above approach # Function to count flips required # to make strings A and B equal def findOperations(A, B, N):
# Stores the count of the
# number of operations
operations = 0
# Stores the length of
# the chosen prefixes
ops = []
# Stores if operations are
# performed even or odd times
invert = False
# Traverse the given string
for i in range (N - 1 , - 1 , - 1 ):
# If current characters in
# the two strings are unequal
if (A[i] ! = B[i]):
# If A[i] is not flipped
if ( not invert):
# Increment count
# of operations
operations + = 1
# Insert the length of
# the chosen prefix
ops.append(i + 1 )
# Update invert to true
invert = True
else :
# If A[i] is flipped
if (invert):
# Increment count
# of operations
operations + = 1
# Insert length of
# the chosen prefix
ops.append(i + 1 )
# Update invert to false
invert = False
# Print the number of
# operations required
print (operations)
# Print the chosen prefix
# length in each operation
if (operations ! = 0 ):
for x in ops:
print (x, end = " " )
# Driver Code if __name__ = = '__main__' :
# Given binary strings
A, B = "001" , "000"
N = len (A)
findOperations(A, B, N)
# This code is contributed by mohit kumar 29. |
// C# program for the above approach using System;
using System.Collections.Generic;
class GFG{
// Function to count flips required // to make Strings A and B equal static void findOperations(String A,
String B, int N)
{ // Stores the count of the
// number of operations
int operations = 0;
// Stores the length of
// the chosen prefixes
List< int > ops = new List< int >();
// Stores if operations are
// performed even or odd times
bool invert = false ;
// Traverse the given String
for ( int i = N - 1; i >= 0; i--)
{
// If current characters in
// the two Strings are unequal
if (A[i] != B[i])
{
// If A[i] is not flipped
if (!invert)
{
// Increment count
// of operations
operations++;
// Insert the length of
// the chosen prefix
ops.Add(i + 1);
// Update invert to true
invert = true ;
}
}
else
{
// If A[i] is flipped
if (invert)
{
// Increment count
// of operations
operations++;
// Insert length of
// the chosen prefix
ops.Add(i + 1);
// Update invert to false
invert = false ;
}
}
}
// Print the number of
// operations required
Console.Write(operations + "\n" );
// Print the chosen prefix
// length in each operation
if (operations != 0)
{
foreach ( int x in ops)
Console.Write(x + " " );
}
} // Driver Code public static void Main(String[] args)
{ // Given binary Strings
String A = "001" , B = "000" ;
int N = A.Length;
findOperations(A, B, N);
} } // This code is contributed by 29AjayKumar |
<script> // JavaScript program for the above approach
// Function to count flips required
// to make Strings A and B equal
function findOperations(A, B, N) {
// Stores the count of the
// number of operations
var operations = 0;
// Stores the length of
// the chosen prefixes
var ops = [];
// Stores if operations are
// performed even or odd times
var invert = false ;
// Traverse the given String
for ( var i = N - 1; i >= 0; i--) {
// If current characters in
// the two Strings are unequal
if (A[i] !== B[i]) {
// If A[i] is not flipped
if (!invert) {
// Increment count
// of operations
operations++;
// Insert the length of
// the chosen prefix
ops.push(i + 1);
// Update invert to true
invert = true ;
}
} else {
// If A[i] is flipped
if (invert) {
// Increment count
// of operations
operations++;
// Insert length of
// the chosen prefix
ops.push(i + 1);
// Update invert to false
invert = false ;
}
}
}
// Print the number of
// operations required
document.write(operations + "<br>" );
// Print the chosen prefix
// length in each operation
if (operations !== 0) {
for (const x of ops) {
document.write(x + " " );
}
}
}
// Driver Code
// Given binary Strings
var A = "001" ,
B = "000" ;
var N = A.length;
findOperations(A, B, N);
</script>
|
2 3 2
Time Complexity: O(N)
Auxiliary Space: O(N)