Related Articles
Minimize swaps of adjacent characters to sort every possible rearrangement of given Binary String
• Last Updated : 04 Jan, 2021

Given a binary string S of length N consisting of 0s, 1s, and “?”, where “?” can be replaced by either 0 or 1, the task is to count the sum of minimum swaps of adjacent characters required to sort every possible arrangement of the string in non-decreasing order Since the answer can be very large, print it modulo 109 + 7.

Examples:

Input: S = “?0?”
Output: 3
Explanation:
Possible rearrangements of the given strings are {“101”, “100”, “000”, “001”}.
Minimum swaps to make “101” non-decreasing, i.e. “011” = 1.
Minimum swaps to make “100” non-decreasing, i.e. “001” = 2.
Minimum swaps to make “000” non-decreasing, i.e. “000” = 0.
Minimum swaps to make “001” non-decreasing, i.e. “001” = 0.
Therefore, total swaps required is 3.

Input: S = “1?00?”
Output: 17

Approach: Consider the following string representation: < Some binary string > 1 <Some string having a number of 0s and b number of ?>

• For each ‘0’ to its right, there is an inversion for every binary string generated for every question mark. So, the inversions here are a*2b.
• For the question mark, there are ways of choosing, such that there are i number of 0s and for each of them there are i inversions.
• There is total of • The above expression can be transformed to b*2(b  – 1). If there are no “?” in the string, the value is 0.
• There the “1” has been counted for a total of a * 2b + b*2(b – 1) inversion.
• For all “?” to the left of “1”, multiply the above value with 2, since a “?” would generate two new strings for every existing string counted.
• After traversing the whole string, return the count.

Follow the steps below to solve the problem:

• Initialize a variable count as 0 to store the sum of the total minimum swaps required for all possible strings.
• Traverse the binary string in a reverse manner.
• For every “1” in the string, calculate the product of the count of 0s and 2(count of ?), i.e. calculate the value of count as a * 2b + b * 2(b – 1).
• If the current character is “0”, then increment the count of 0s.
• Otherwise, multiply the value of count by 2 and repeat the above process.
• After completing the above steps, print the value of count as the result.

Below is the implementation of the above approach:

## C++14

 // C++ program for the above approach#include#define MOD  1000000007using namespace std; // Precalculate the values of power of 2vector<int> MEM = { 1, 2, 4, 8, 16, 32, 64,                    128, 256, 512, 1024,                    2048, 4096 }; // Function to calculate 2 ^ N % modint mod_pow2(int n){    while (n >= MEM.size())        MEM.push_back((MEM[-1] * 2) % MOD);     return MEM[n];} // Function to find sum of inversionsint inversions(string bstr){         // Initialise a list of 0s and ?s    int total = 0, zeros = 0, questions = 0;     // Traverse the string in the    // reversed manner    reverse(bstr.begin(),bstr.end());     for(char x: bstr)    {        int q;                 // If the current character is 1        if (x == '1')        {                     // Effectively calculate a * b^(b-1)            int z = zeros * mod_pow2(questions);                         if (questions == 0)                q = 0;            else                q = questions * mod_pow2(                    questions - 1);                         total = (total + z + q) % MOD;        }                 // If the current character is 0        else if (x == '0')        {            //Increment count of zeroes            zeros += 1;        }        else        {                         // Double count the zeroes            total *= 2;                         // Find b * 2^(b-1)            int z = zeros * mod_pow2(questions);            if (questions == 0)                q = 0;            else                q = questions * mod_pow2(                    questions - 1);                         total = (total + z + q) % MOD;                         // Increment count of questions            questions += 1;        }    }         // Return the final count    return total;} // Driver Codeint main(){         // Given string S    string S = "?0?";     // Function Call    cout << inversions(S);} // This code is contributed by mohit kumar 29

## Java

 // Java program for the above approachimport java.io.*;import java.util.*; class GFG{     static int MOD = 1000000007; static Integer array[] = { 1, 2, 4, 8, 16, 32, 64,                           128, 256, 512, 1024,                           2048, 4096 }; // Precalculate the values of power of 2static Vector MEM = new Vector(    Arrays.asList(array)); // Function to calculate 2 ^ N % modstatic int mod_pow2(int n){    while (n >= MEM.size())        MEM.add((MEM.get(            MEM.size() - 1) * 2) % MOD);         return MEM.get(n);} // Function to find sum of inversionsstatic int inversions(char[] bstr){         // Initialise a list of 0s and ?s    int total = 0, zeros = 0, questions = 0;         // Traverse the string in the    // reversed manner    int j = bstr.length - 1;    for(int i = 0; i < bstr.length / 2; i++)    {        char temp = bstr[i];        bstr[i] = bstr[j];        bstr[j] = temp;        j--;    }         for(char x : bstr)    {        int q;                 // If the current character is 1        if (x == '1')        {                         // Effectively calculate a * b^(b-1)            int z = zeros * mod_pow2(questions);                         if (questions == 0)                q = 0;            else                q = questions * mod_pow2(                    questions - 1);                         total = (total + z + q) % MOD;        }                     // If the current character is 0        else if (x == '0')        {                         // Increment count of zeroes            zeros += 1;        }        else        {                         // Double count the zeroes            total *= 2;                         // Find b * 2^(b-1)            int z = zeros * mod_pow2(questions);            if (questions == 0)                q = 0;            else                q = questions * mod_pow2(                    questions - 1);                         total = (total + z + q) % MOD;                         // Increment count of questions            questions += 1;        }    }         // Return the final count    return total;} // Driver Code public static void main(String[] args){         // Given string S    char S[] = "?0?".toCharArray();         // Function Call    System.out.println(inversions(S));}} // This code is contributed by divyeshrabadiya07

## Python3

 # Python3 program for the above approach MOD = 10**9 + 7 # Precalculate the values of power of 2MEM = [1, 2, 4, 8, 16, 32, 64, 128,       256, 512, 1024, 2048, 4096] # Function to calculate 2 ^ N % moddef mod_pow2(n):         while n >= len(MEM):        MEM.append((MEM[-1] * 2) % MOD)             return MEM[n] # Function to find sum of inversionsdef inversions(bstr):     # Initialise a list of 0s and ?s    total, zeros, questions = (0, )*3     # Traverse the string in the    # reversed manner    for x in reversed(bstr):         # If the current character is 1        if x == '1':             # Effectively calculate a * b^(b-1)            z = zeros * mod_pow2(questions)                         if questions == 0:                q = 0            else:                 q = questions * mod_pow2(questions - 1)                              total = (total + z + q) % MOD         # If the current character is 0        elif x == '0':                     # Increment count of zeroes            zeros += 1         else:                     # Double count the zeroes            total *= 2             # Find b * 2^(b-1)            z = zeros * mod_pow2(questions)            if questions == 0:                q = 0            else:                 q = questions * mod_pow2(questions - 1)                              total = (total + z + q) % MOD             # Increment count of questions            questions += 1         # Return the final count    return total # Driver Codedef main():     # Given string S    S = "?0?"     # Function Call    print(inversions(S))  if __name__ == "__main__":    main()

## C#

 // C# program for the above approachusing System;using System.Collections.Generic;class GFG {   static int MOD = 1000000007;   // Precalculate the values of power of 2  static List<int> MEM = new List<int>(new int[] { 1, 2, 4, 8, 16, 32, 64,                                                  128, 256, 512, 1024,                                                  2048, 4096 });   // Function to calculate 2 ^ N % mod  static int mod_pow2(int n)  {    while (n >= MEM.Count)      MEM.Add((MEM[MEM.Count - 1] * 2) % MOD);     return MEM[n];  }   // Function to find sum of inversions  static int inversions(char[] bstr)  {     // Initialise a list of 0s and ?s    int total = 0, zeros = 0, questions = 0;     // Traverse the string in the    // reversed manner    Array.Reverse(bstr);     foreach(char x in bstr)    {      int q;       // If the current character is 1      if (x == '1')      {         // Effectively calculate a * b^(b-1)        int z = zeros * mod_pow2(questions);         if (questions == 0)          q = 0;        else          q = questions * mod_pow2(          questions - 1);         total = (total + z + q) % MOD;      }       // If the current character is 0      else if (x == '0')      {        // Increment count of zeroes        zeros += 1;      }      else      {         // Double count the zeroes        total *= 2;         // Find b * 2^(b-1)        int z = zeros * mod_pow2(questions);        if (questions == 0)          q = 0;        else          q = questions * mod_pow2(          questions - 1);         total = (total + z + q) % MOD;         // Increment count of questions        questions += 1;      }    }     // Return the final count    return total;  }   // Driver code  static void Main()  {     // Given string S    char[] S = "?0?".ToCharArray();     // Function Call    Console.WriteLine(inversions(S));  }} // This code is contributed by divyesh072019
Output:
3

Time Complexity: O(N)
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up