Open In App

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

Improve
Improve
Like Article
Like
Save
Share
Report

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)


 



Last Updated : 22 Apr, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads