Minimize swaps of adjacent characters to sort every possible rearrangement of given Binary String
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<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> |
3
Time Complexity: O(N)
Auxiliary Space: O(N)
Please Login to comment...