Minimize flips on adjacent 2 to 3 bits to generate a binary string of all 1s
Given a binary string S consisting of 0’s and 1’s, The task is to find the minimum number of flips required to generate a binary string of all ones. The flip is performed on either two or three adjacent indices.
Examples:
Input: S = “0010”
Output: 2
Explanation: Operations performed are: 0010 -> 0001 -> 1111Input: S = “0011110”
Output: 3
Explanation: Operations performed are: 0011110 -> 1111110 -> 1111000 -> 1111111
Approach: The basic idea to solve this problem is to perform flips on the first 2 or 3 characters and add the result of recursion with the next positions. It’s just a recursive brute forcing of all possibilities. For every index of the string, try two adjacent flips and three adjacent flips and then recurse on that subproblem. One important thing is that the result is independent of the order of the flips.
Follow the below steps to solve the problem:
- If the given string doesn’t consist of any zeros then return “0” and if there are only “1’s” then no flip is needed.
- If the given string, at any moment becomes equal to “00” or “000” then return “1” as only 1 flip is needed to make it all ones.
- We need a list for storing and comparing minimum possibilities at any moment of the recursive call.
- If the string starts with “0” and the length of the string is greater than 2 or 3 then we flip the first two or first three characters and recursively call again for the next index.
- If strings start with “1“, we remove it by recursively calling it for the rest of the part.
- Now in the case of “1“, if “0” is present at the first two or three positions then we flip the first two or three positions and recursively call for the rest of the part along with appending/adding results to the lists.
- Once a cycle is completed we return the minimum of all the elements stored in the list.
Below is the implementation of the above approach:
C++
#include <iostream> #include <string> #include <algorithm> #include <climits> using namespace std; string flipString(string string, int n) { string temp = string; for ( int i = 0; i < n; i++) { if (temp[i] == '0' ) { temp[i] = '1' ; } else { temp[i] = '0' ; } } return temp; } int minimumFlips(string string) { // No flip needed if (string.find( '0' ) == string::npos) { return 0; } // Flip the whole string at once if (string == "00" || string == "000" ) { return 1; } // For tracking minimum flips int flips = INT_MAX; // Flip if string starts with zero if (string[0] == '0' ) { // Flip first 2 and call recursively if (string.length() > 2) { flips = min(flips, 1 + minimumFlips(flipString(string, 2).substr(1))); } // Flip first 3 and call recursively if (string.length() > 3) { flips = min(flips, 1 + minimumFlips(flipString(string, 3).substr(1))); } } else { // No flip + recursion flips = min(flips, minimumFlips(string.substr(1))); // Flip if zero is at 2nd position if (string[1] == '0' ) { // Flip first 2 and call recursively flips = min(flips, 1 + minimumFlips(flipString(string.substr(1), 2))); } // Flip if zero is at 3rd position if (string[2] == '0' ) { // Flip first 3 and call recursively flips = min(flips, 1 + minimumFlips(flipString(string.substr(1), 3))); } } return flips; } // Driver Code int main() { cout << minimumFlips( "0010" ) << endl; return 0; } |
Java
import java.util.Arrays; public class HelloWorld { public static String flipString(String str, int n) { char [] temp1 = new char [str.length()]; for ( int i = 0 ; i < n; i++) { if (str.charAt(i) == '0' ) { temp1[i] = '1' ; } else { temp1[i] = '0' ; } } String temp2 = new String(temp1); return temp2; } public static int minimumFlips(String str) { // No flip needed if (str.contains( "0" ) == true ) { return 0 ; } // Flip the whole string at once if (str.equals( "00" ) || str.equals( "000" )) { return 1 ; } // For tracking minimum flips int flips = Integer.MAX_VALUE; // Flip if string starts with zero if (str.charAt( 0 ) == '0' ) { // Flip first 2 and call recursively if (str.length() > 2 ) { flips = Math.min(flips, 1 + minimumFlips(flipString(str, 2 ).substring( 1 ))); } // Flip first 3 and call recursively if (str.length() > 3 ) { flips = Math.min(flips, 1 + minimumFlips(flipString(str, 3 ).substring( 1 ))); } } else { // No flip + recursion flips = Math.min(flips, minimumFlips(str.substring( 1 ))); // Flip if zero is at 2nd position if (str.charAt( 1 ) == '0' ) { // Flip first 2 and call recursively flips = Math.min(flips, 1 + minimumFlips(flipString(str.substring( 1 ), 2 ))); } // Flip if zero is at 3rd position if (str.charAt( 2 ) == '0' ) { // Flip first 3 and call recursively flips = Math.min(flips, 1 + minimumFlips(flipString(str.substring( 1 ), 3 ))); } } return flips; } public static void main(String[] args) { System.out.println(minimumFlips( "0010" ) + 2 ); } } |
Python3
# Python program for the above approach def minimumFlips(string): # No flip needed if "0" not in string: return 0 # Flip the whole string at once if string in ( "00" , "000" ): return 1 # Flip 1st 2 / 3 characters def flip(n): return string[:n]\ .translate({ 48 : 49 , 49 : 48 })\ + string[n:] # For tracking minimum flips flips = [ float ( 'inf' )] # Flip if string starts with zero if string.startswith( "0" ): # Flip first 2 and call recursively if len (string) > 2 : flips.append( 1 + minimumFlips(flip( 2 )[ 1 :])) # Flip first 3 and call recursively if len (string) > 3 : flips.append( 1 + minimumFlips(flip( 3 )[ 1 :])) # If string starts with "1" else : # No flip + recursion flips.append(minimumFlips(string[ 1 :])) # Flip if zero is at 2nd position if "0" in string[: 2 ]: # Flip first 2 and call recursively flips.append( 1 + minimumFlips(flip( 2 ))) # Flip if zero is at 2nd position if "0" in string[: 3 ]: # Flip first 3 and call recursively flips.append( 1 + minimumFlips(flip( 3 ))) return min (flips) # Driver code if __name__ = = "__main__" : print (minimumFlips( "0010" )) |
C#
using System; using System.Collections; using System.Collections.Generic; using System.Linq; class HelloWorld { public static string flipString( string str, int n) { char [] temp1 = new char [str.Length]; for ( int i = 0; i < n; i++) { if (str[i] == '0' ) { temp1[i] = '1' ; } else { temp1[i] = '0' ; } } string temp2 = new string (temp1); return temp2; } public static int minimumFlips( string str) { // No flip needed if (str.Contains( '0' ) == true ) { return 0; } // Flip the whole string at once if (str == "00" || str == "000" ) { return 1; } // For tracking minimum flips int flips = 2147483647; // Flip if string starts with zero if (str[0] == '0' ) { // Flip first 2 and call recursively if (str.Length > 2) { flips = Math.Min(flips, 1 + minimumFlips(flipString(str, 2).Substring(1))); } // Flip first 3 and call recursively if (str.Length > 3) { flips = Math.Min(flips, 1 + minimumFlips(flipString(str, 3).Substring(1))); } } else { // No flip + recursion flips = Math.Min(flips, minimumFlips(str.Substring(1))); // Flip if zero is at 2nd position if (str[1] == '0' ) { // Flip first 2 and call recursively flips = Math.Min(flips, 1 + minimumFlips(flipString(str.Substring(1), 2))); } // Flip if zero is at 3rd position if (str[2] == '0' ) { // Flip first 3 and call recursively flips = Math.Min(flips, 1 + minimumFlips(flipString(str.Substring(1), 3))); } } return flips; } static void Main() { Console.WriteLine(minimumFlips( "0010" ) + 2); } } // The code is contributed by Nidhi goel. |
Javascript
function minimumFlips(string) { // No flip needed if (!string.includes( "0" )) { return 0; } // Flip the whole string at once if (string === "00" || string === "000" ) { return 1; } // For tracking minimum flips let flips = [Infinity]; // Flip if string starts with zero if (string.startsWith( "0" )) { // Flip first 2 and call recursively if (string.length > 2) { flips.push(1 + minimumFlips(flip(2).slice(1))); } // Flip first 3 and call recursively if (string.length > 3) { flips.push(1 + minimumFlips(flip(3).slice(1))); } } else { // No flip + recursion flips.push(minimumFlips(string.slice(1))); // Flip if zero is at 2nd position if (string.slice(0, 2).includes( "0" )) { // Flip first 2 and call recursively flips.push(1 + minimumFlips(flip(2))); } // Flip if zero is at 2nd position if (string.slice(0, 3).includes( "0" )) { // Flip first 3 and call recursively flips.push(1 + minimumFlips(flip(3))); } } return Math.min(...flips); function flip(n) { return ( string .slice(0, n) .split( "" ) .map(c => (c === "0" ? "1" : "0" )) .join( "" ) + string.slice(n) ); } } // Driver code console.log(minimumFlips( "0010" )); # This code is contributed by Shivam Tiwari |
2
Time Complexity: O(N!)
Auxiliary Space: O(N)
Please Login to comment...