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++ 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 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 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# 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 |
<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)