Skip to content
Related Articles
Get the best out of our app
GeeksforGeeks App
Open App
geeksforgeeks
Browser
Continue

Related Articles

Minimize swaps of adjacent characters to sort every possible rearrangement of given Binary String

Improve Article
Save Article
Like Article
Improve Article
Save Article
Like Article

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 _{i}^{b}\textrm{C}          ways of choosing, such that there are i number of 0s and for each of them there are i inversions.
  • There is total of  \sum_{i = 1}^{N}(_{i}^{b}\textrm{C})
  • 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<bits/stdc++.h>
#define MOD  1000000007
using namespace std;
 
// Precalculate the values of power of 2
vector<int> MEM = { 1, 2, 4, 8, 16, 32, 64,
                    128, 256, 512, 1024,
                    2048, 4096 };
 
// Function to calculate 2 ^ N % mod
int mod_pow2(int n)
{
    while (n >= MEM.size())
        MEM.push_back((MEM[-1] * 2) % MOD);
 
    return MEM[n];
}
 
// Function to find sum of inversions
int 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 Code
int 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 approach
import 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 2
static Vector<Integer> MEM = new Vector<Integer>(
    Arrays.asList(array));
 
// Function to calculate 2 ^ N % mod
static 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 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
    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 2
MEM = [1, 2, 4, 8, 16, 32, 64, 128,
       256, 512, 1024, 2048, 4096]
 
# Function to calculate 2 ^ N % mod
def mod_pow2(n):
     
    while n >= len(MEM):
        MEM.append((MEM[-1] * 2) % MOD)
         
    return MEM[n]
 
# Function to find sum of inversions
def 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 Code
def main():
 
    # Given string S
    S = "?0?"
 
    # Function Call
    print(inversions(S))
 
 
if __name__ == "__main__":
    main()

C#




// C# program for the above approach
using 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

Javascript




<script>
    // Javascript program for the above approach
     
    let MOD = 1000000007;
  
    // Precalculate the values of power of 2
    let MEM = [ 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 ];
 
    // Function to calculate 2 ^ N % mod
    function mod_pow2(n)
    {
      while (n >= MEM.length)
        MEM.push((MEM[MEM.length - 1] * 2) % MOD);
 
      return MEM[n];
    }
 
    // Function to find sum of inversions
    function inversions(bstr)
    {
 
      // Initialise a list of 0s and ?s
      let total = 0, zeros = 0, questions = 0;
 
      // Traverse the string in the
      // reversed manner
      bstr.reverse();
 
      for(let i = 0; i < bstr.length; i++)
      {
        let q;
 
        // If the current character is 1
        if (bstr[i] == '1')
        {
 
          // Effectively calculate a * b^(b-1)
          let 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 (bstr[i] == '0')
        {
          // Increment count of zeroes
          zeros += 1;
        }
        else
        {
 
          // Double count the zeroes
          total *= 2;
 
          // Find b * 2^(b-1)
          let 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;
    }
     
    // Given string S
    let S = "?0?".split('');
  
    // Function Call
    document.write(inversions(S));
 
// This code is contributed by suresh07.
</script>

Output: 

3

 

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

 


My Personal Notes arrow_drop_up
Last Updated : 22 Apr, 2021
Like Article
Save Article
Similar Reads
Related Tutorials