Convert given Binary String to another in minimum operations by flipping all bits except any 1 - GeeksforGeeks

11 Feb, 2022
Given two binary strings s1 and s2, the task is to count the minimum operations to convert string s1 to s2. In one operation a set bit can be chosen and all other bits except that is flipped. If it is not possible to convert s1-> s2 print -1.
Examples: 
Input: s1 = “100010111”   s2 = “101101100”Output: 3Explanation: In the first operation hold 1 at 6 th index and convert remaining to logical NOT: 100010111→011101100 .In the second operation hold 1 at 1st index  and convert remaining to logical NOT: 011101100→110010011.In the third operation hold 1 at 0th index and convert remaining to logical NOT: 110010011→101101100.So 3 operations.
Input: s1=”11111′′  s2 = “00000”Output: -1
Approach: It can be seen choosing the same index of 1 after two operations string remains the same as the original. So different index should be chosen for each operation on doing so “10” in string s1 can be converted to a string “01” in string s2 with two operations. So the answer is dependent on minimizing the number of “10” and “01” in strings s1 and s2. If at any index “0(s1) – 1(s2) “ && “1(s1) – 0(s2)”  are equal in number then there is an answer else -1.
“01” (on choosing 1 at index1) -> “11”(on choosing 1 at index2)  -> “10”
Using this conclusion: It can be even possible that minimum “0(s1) – 1(s2) ” && “1(s1) – 0(s2)”  pairs can be obtained by doing 1 operation initially. In the cases where 1 (s1)-> 1(s2) or 1(s1) -> 0(s2).
Follow these steps to solve this problem:
Initialize the variable res = INT_MAX
Initialize the variable ops1= -1 to store the operations required to convert string s1 to s2 without any modification.
Now check if it is possible to minimize operations by doing 1 initial modification in case of (1(s1)-> 1(s2)).
Store the operations in ops2 variable and store the minimum in the res by doing min(res,ops2).
Now check if it is possible to minimize operations by doing 1 initial modification in case of (1(s1)-> 0(s2)).
Store the operations in ops3 variable and store the minimum in the res by doing min(res,ops3).
If res is equal to INT_MAX it means it is not possible to convert string s1 -> s2 so print -1.
Else print the res.
Below is the implementation of the above approach:
C++14
Python3
C#
Javascript
Java
// C++ program for the above approach#include <bits/stdc++.h>using namespace std; // Function to count the "0(s1)-1(s2)"// && "1(s1)- 0(s2)" pairsint count_operations(string s1, string s2){    int n = s1.size();         // Initializing to 0 initially    int cnt10 = 0, cnt01 = 0;    for (int i = 0; i < n; i++) {        if (s1[i] != s2[i]) {            if (s1[i] == '0')                cnt01++;            else                cnt10++;        }    }         // Equal 0(s1)-1(s2) and 1(s1)- 0(s2) pairs    // To convert 1 pair 2 operations are required    // so 2 * cnt01    if (cnt01 == cnt10)        return 2 * cnt01;    return -1;} // Function to do one operation of// modifying the string s1bool modify_string(string& s1, string& s2,                   char c){    int n = s1.size();    int idx = -1;         // Find the index of occurrence of    // 1(s1)- c(s2) in s1    for (int i = 0; i < n; i++) {        if (s1[i] == '1' && s2[i] == c) {                         // Break if found            idx = i;            break;        }    }    if (idx == -1)        return 0;         // Flip the remaining except that index    for (int i = 0; i < n; i++) {        if (i == idx)            continue;        if (s1[i] == '1')            s1[i] = '0';        else            s1[i] = '1';    }    return 1;} // Function to find the minimum operations// to convert the string s1 to string s2int find_min_operations(string s1, string s2){    int res = INT_MAX;         // Case -1 Initial strings itself    int ops1 = count_operations(s1, s2);       if (ops1 != -1)        res = min(res, ops1);     string a = s1, b = s2;         // Case -2 Doing 1 modification initially    // for 1(s1)-1(s2)    if (modify_string(a, b, '1')) {           int ops2 = count_operations(a, b);                 // Take minimum        if (ops2 != -1)            res = min(res, 1 + ops2);            }       // Case-3 doing 1 modification initially    // for 1(s1) - 0(s2)    a = s1, b = s2;    if (modify_string(a, b, '0')) {        int ops3 = count_operations(a, b);                 // Take minimum        if (ops3 != -1)            res = min(res, 1 + ops3);    }     if (res == INT_MAX)        return -1;    else        return res;} // Driver codeint main(){    string s1 = "100010111";    string s2 = "101101100";         // Function call    cout << find_min_operations(s1, s2) << endl;    return 0;}
# Python program for the above approachINT_MAX = 2147483647; # Function to count the "0(s1)-1(s2)"# && "1(s1)- 0(s2)" pairsdef count_operations (s1, s2):    n = len(s1);     # Initializing to 0 initially    cnt10 = 0    cnt01 = 0;    for i in range(n):        if (s1[i] != s2[i]):            if (s1[i] == '0'):                cnt01 += 1            else:                cnt10 += 1     # Equal 0(s1)-1(s2) and 1(s1)- 0(s2) pairs    # To convert 1 pair 2 operations are required    # so 2 * cnt01    if (cnt01 == cnt10):        return 2 * cnt01;    return -1; # Function to do one operation of# modifying the let s1def modify_string (s1, s2, c):    n = len(s1);    idx = -1;     # Find the index of occurrence of    # 1(s1)- c(s2) in s1    for i in range(n):        if (s1[i] == '1' and s2[i] == c):             # Break if found            idx = i;            break;    if (idx == -1):        return 0;     # Flip the remaining except that index    for i in range(n):        if (i == idx):            continue;        if (s1[i] == '1'):            s1[i] = '0';        else:            s1[i] = '1';    return 1;  # Function to find the minimum operations# to convert the let s1 to let s2def find_min_operations (s1, s2):    res = 10 ** 9;     # Case -1 Initial strings itself    ops1 = count_operations(s1, s2);    if (ops1 != -1):        res = min(res, ops1);     a = s1    b = s2;    # Case -2 Doing 1 modification initially    # for 1(s1)-1(s2)    if (modify_string(a, b, '1')):        ops2 = count_operations(a, b);         # Take minimum        if (ops2 != -1):            res = min(res, 1 + ops2);     # Case-3 doing 1 modification initially    # for 1(s1) - 0(s2)    a = s1    b = s2;    if (modify_string(a, b, '0')):        ops3 = count_operations(a, b);         # Take minimum        if (ops3 != -1):            res = min(res, 1 + ops3);     if (res == 10 ** 9):        return -1;    else:        return res;  # Driver codes1 = "100010111";s2 = "101101100";s1 = list(s1);s2 = list(s2); # Function callprint(find_min_operations(s1, s2)); # This code is contributed by gfgking
// C# program for the above approachusing System;class GFG {   // Function to count the "0(s1)-1(s2)"  // && "1(s1)- 0(s2)" pairs  static int count_operations(string s1, string s2)  {    int n = s1.Length;     // Initializing to 0 initially    int cnt10 = 0, cnt01 = 0;    for (int i = 0; i < n; i++) {      if (s1[i] != s2[i]) {        if (s1[i] == '0')          cnt01++;        else          cnt10++;      }    }     // Equal 0(s1)-1(s2) and 1(s1)- 0(s2) pairs    // To convert 1 pair 2 operations are required    // so 2 * cnt01    if (cnt01 == cnt10)      return 2 * cnt01;    return -1;  }   // Function to do one operation of  // modifying the string s1  static int modify_string(ref string s1, ref string s2,                           char c)  {    int n = s1.Length;    char[] str1 = s1.ToCharArray();    char[] str2 = s2.ToCharArray();     int idx = -1;     // Find the index of occurrence of    // 1(s1)- c(s2) in s1    for (int i = 0; i < n; i++) {      if (str1[i] == '1' && str2[i] == c) {         // Break if found        idx = i;        break;      }    }    if (idx == -1)      return 0;     // Flip the remaining except that index    for (int i = 0; i < n; i++) {      if (i == idx)        continue;      if (str1[i] == '1')        str1[i] = '0';      else        str1[i] = '1';    }    s1 = new string(str1);    s2 = new string(str2);    return 1;  }   // Function to find the minimum operations  // to convert the string s1 to string s2  static int find_min_operations(string s1, string s2)  {    int res = Int32.MaxValue;     // Case -1 Initial strings itself    int ops1 = count_operations(s1, s2);     if (ops1 != -1)      res = Math.Min(res, ops1);     string a = s1, b = s2;     // Case -2 Doing 1 modification initially    // for 1(s1)-1(s2)    if (modify_string(ref a, ref b, '1') > 0) {      int ops2 = count_operations(a, b);       // Take minimum      if (ops2 != -1)        res = Math.Min(res, 1 + ops2);    }     // Case-3 doing 1 modification initially    // for 1(s1) - 0(s2)    a = s1;    b = s2;    if (modify_string(ref a, ref b, '0') > 0) {      int ops3 = count_operations(a, b);       // Take minimum      if (ops3 != -1)        res = Math.Min(res, 1 + ops3);    }     if (res == Int32.MaxValue)      return -1;    else      return res;  }   // Driver code  public static void Main()  {    string s1 = "100010111";    string s2 = "101101100";     // Function call    Console.WriteLine(find_min_operations(s1, s2));  }} // This code is contributed by ukasp.
<script>    // JavaScript program for the above approach    const INT_MAX = 2147483647;     // Function to count the "0(s1)-1(s2)"    // && "1(s1)- 0(s2)" pairs    const count_operations = (s1, s2) => {        let n = s1.length;         // Initializing to 0 initially        let cnt10 = 0, cnt01 = 0;        for (let i = 0; i < n; i++) {            if (s1[i] !== s2[i]) {                if (s1[i] === '0')                    cnt01++;                else                    cnt10++;            }        }         // Equal 0(s1)-1(s2) and 1(s1)- 0(s2) pairs        // To convert 1 pair 2 operations are required        // so 2 * cnt01        if (cnt01 === cnt10)            return 2 * cnt01;        return -1;    }     // Function to do one operation of    // modifying the let s1    const modify_string = (s1, s2, c) => {        let n = s1.length;        let idx = -1;         // Find the index of occurrence of        // 1(s1)- c(s2) in s1        for (let i = 0; i < n; i++) {            if (s1[i] === '1' && s2[i] === c) {                 // Break if found                idx = i;                break;            }        }        if (idx === -1)            return 0;         // Flip the remaining except that index        for (let i = 0; i < n; i++) {            if (i === idx)                continue;            if (s1[i] == '1')                s1[i] = '0';            else                s1[i] = '1';        }        return 1;    }     // Function to find the minimum operations    // to convert the let s1 to let s2    const find_min_operations = (s1, s2) => {        let res = INT_MAX;         // Case -1 Initial strings itself        let ops1 = count_operations(s1, s2);        if (ops1 !== -1)            res = Math.min(res, ops1);         let a = s1, b = s2;        // Case -2 Doing 1 modification initially        // for 1(s1)-1(s2)        if (modify_string(a, b, '1')) {            let ops2 = count_operations(a, b);             // Take minimum            if (ops2 !== -1)                res = Math.min(res, 1 + ops2);        }         // Case-3 doing 1 modification initially        // for 1(s1) - 0(s2)        a = s1, b = s2;        if (modify_string(a, b, '0')) {            let ops3 = count_operations(a, b);             // Take minimum            if (ops3 !== -1)                res = Math.min(res, 1 + ops3);        }         if (res === INT_MAX)            return -1;        else            return res;    }     // Driver code    let s1 = "100010111";    let s2 = "101101100";    s1 = s1.split('');    s2 = s2.split('');         // Function call    document.write(find_min_operations(s1, s2));     // This code is contributed by rakeshsahni </script>
// Java program for the above approachimport java.util.*;public class GFG {   // Function to count the "0(s1)-1(s2)"  // && "1(s1)- 0(s2)" pairs  static int count_operations(String s1, String s2)  {    int n = s1.length();     // Initializing to 0 initially    int cnt10 = 0, cnt01 = 0;    for (int i = 0; i < n; i++) {      if (s1.charAt(i) != s2.charAt(i)) {        if (s1.charAt(i) == '0')          cnt01++;        else          cnt10++;      }    }     // Equal 0(s1)-1(s2) and 1(s1)- 0(s2) pairs    // To convert 1 pair 2 operations are required    // so 2 * cnt01    if (cnt01 == cnt10)      return 2 * cnt01;    return -1;  }   // Function to do one operation of  // modifying the string s1  static int modify_string(String s1, String s2,                           char c)  {    int n = s1.length();    char[] str1 = s1.toCharArray();    char[] str2 = s2.toCharArray();     int idx = -1;     // Find the index of occurrence of    // 1(s1)- c(s2) in s1    for (int i = 0; i < n; i++) {      if (str1[i] == '1' && str2[i] == c) {         // Break if found        idx = i;        break;      }    }    if (idx == -1)      return 0;     // Flip the remaining except that index    for (int i = 0; i < n; i++) {      if (i == idx)        continue;      if (str1[i] == '1')        str1[i] = '0';      else        str1[i] = '1';    }    s1 = new String(str1);    s2 = new String(str2);    return 1;  }   // Function to find the minimum operations  // to convert the string s1 to string s2  static int find_min_operations(String s1, String s2)  {    int res = Integer.MAX_VALUE;     // Case -1 Initial strings itself    int ops1 = count_operations(s1, s2);    ops1 /= 2;         if (ops1 != -1)      res = Math.min(res, ops1);     String a = s1, b = s2;     // Case -2 Doing 1 modification initially    // for 1(s1)-1(s2)    if (modify_string(a, b, '1') > 0) {      int ops2 = count_operations(a, b);       // Take minimum      if (ops2 != -1)        res = Math.min(res, 1 + ops2);    }     // Case-3 doing 1 modification initially    // for 1(s1) - 0(s2)    a = s1;    b = s2;    if (modify_string(a, b, '0') > 0) {      int ops3 = count_operations(a, b);       // Take minimum      if (ops3 != -1)        res = Math.min(res, 1 + ops3);    }     if (res == Integer.MAX_VALUE)      return -1;    else      return res;  }   // Driver code  public static void main(String args[])  {    String s1 = "100010111";    String s2 = "101101100";     // Function call    System.out.println(find_min_operations(s1, s2));  }} // This code is contributed by Samim Hossain Mondal.
  
3
 
Time Complexity: O(N) where N is the length of the string.Space Complexity: O(N)
 
rakeshsahni
gfgking
ukasp
samim2000
sumitgumber28
simmytarika5
Algo-Geek 2021
binary-string
Algo Geek
Greedy
Strings
Strings
Greedy
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Generate string after adding spaces at specific positions in a given String
Find sum of factorials till N factorial (1! + 2! + 3! + ... + N!)
Maximize partitions that if sorted individually makes the whole Array sorted
Maximum count of adjacent pairs with even sum in given Circular Array
Create a balanced BST using vector in C++ STL
Dijkstra's shortest path algorithm | Greedy Algo-7
Kruskal’s Minimum Spanning Tree Algorithm | Greedy Algo-2
Prim’s Minimum Spanning Tree (MST) | Greedy Algo-5
Program for array rotation
Write a program to print all permutations of a given string