Count of substrings with equal ratios of 0s and 1s till ith index in given Binary String
Given a binary string S, the task is to print the maximum number of substrings with equal ratios of 0s and 1s till the ith index from the start.
Examples:
Input: S = “110001”
Output: {1, 2, 1, 1, 1, 2}
Explanation: The given string can be partitioned into the following equal substrings:
- Valid substrings upto index 0 : “1”, possible no. of substrings = 1
- Valid substrings upto index 1 : “1”, “B”, possible no. of substrings = 2
- Valid substrings upto index 2 : “110”, possible no. of substrings = 1
- Valid substrings upto index 3 : “1100”, possible no. of substrings = 1
- Valid substrings upto index 4 : “11000”, possible no. of substrings = 1
- Valid substrings upto index 5 : “1100”, “01”, possible no. of substrings = 2
Input: S = “010100001”
Output: {1, 1, 1, 2, 1, 2, 1, 1, 3}
Approach: The task can be solved using mathematical concepts & HashMap to store the frequencies of pairs Follow the below steps to solve the problem:
- Create two prefix arrays for occurrences of 0s and 1s say pre0[] and pre1[] respectively.
- For each prefix, label it with a pair (a, b) where a = frequency of ‘0’ and b = frequency of ‘1’ in this prefix. Divide a and b by gcd(a, b) to get the simplest form.
- Iterate over all prefixes, and store the answer for the prefix as the current number of occurrences of this pair.
Below is the implementation of the above approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; // Function to retuan a prefix array of // equal partitions of the given string // consisting of 0s and 1s void equalSubstrings(string s) { // Length of the string int n = s.size(); // Prefix arrays for 0s and 1s int pre0[n] = { 0 }, pre1[n] = { 0 }; // If character at index 0 is 0 if (s[0] == '0' ) { pre0[0] = 1; } // If character at index 0 is 1 else { pre1[0] = 1; } // Filling the prefix arrays for ( int i = 1; i < n; i++) { if (s[i] == '0' ) { pre0[i] = pre0[i - 1] + 1; pre1[i] = pre1[i - 1]; } else { pre0[i] = pre0[i - 1]; pre1[i] = pre1[i - 1] + 1; } } // Vector to store the answer vector< int > ans; // Map to store the ratio map<pair< int , int >, int > mp; for ( int i = 0; i < n; i++) { // Find the gcd of pre0[i] and pre1[i] int x = __gcd(pre0[i], pre1[i]); // Converting the elements in // simplest form int l = pre0[i] / x, r = pre1[i] / x; // Update the value in map mp[{ l, r }]++; // Store this in ans ans.push_back(mp[{ l, r }]); } // Return the ans vector for ( auto i : ans) cout << i << " " ; } // Driver Code int main() { string s = "001110" ; equalSubstrings(s); return 0; } |
Java
// Java program for the above approach import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; class GFG { // Function to retuan a prefix array of // equal partitions of the given string // consisting of 0s and 1s public static void equalSubstrings(String s) { // Length of the string int n = s.length(); // Prefix arrays for 0s and 1s int [] pre0 = new int [n]; int [] pre1 = new int [n]; Arrays.fill(pre0, 0 ); Arrays.fill(pre1, 0 ); // If character at index 0 is 0 if (s.charAt( 0 ) == '0' ) { pre0[ 0 ] = 1 ; } // If character at index 0 is 1 else { pre1[ 0 ] = 1 ; } // Filling the prefix arrays for ( int i = 1 ; i < n; i++) { if (s.charAt(i) == '0' ) { pre0[i] = pre0[i - 1 ] + 1 ; pre1[i] = pre1[i - 1 ]; } else { pre0[i] = pre0[i - 1 ]; pre1[i] = pre1[i - 1 ] + 1 ; } } // Vector to store the answer ArrayList<Integer> ans = new ArrayList<Integer>(); // Map to store the ratio HashMap<String, Integer> mp = new HashMap<String, Integer>(); for ( int i = 0 ; i < n; i++) { // Find the gcd of pre0[i] and pre1[i] int x = __gcd(pre0[i], pre1[i]); // Converting the elements in // simplest form int l = pre0[i] / x, r = pre1[i] / x; String key = l + "," + r; // Update the value in map if (mp.containsKey(key)) mp.put(key, mp.get(key) + 1 ); else mp.put(key, 1 ); // Store this in ans ans.add(mp.get(key)); } // Return the ans vector for ( int i : ans) System.out.print(i + " " ); } public static int __gcd( int a, int b) { if (b == 0 ) return a; return __gcd(b, a % b); } // Driver Code public static void main(String args[]) { String s = "001110" ; equalSubstrings(s); } } // This code is contributed by gfgking. |
Python3
# Python program for the above approach def __gcd(a, b): if (b = = 0 ): return a return __gcd(b, a % b) # Function to retuan a prefix array of # equal partitions of the given string # consisting of 0s and 1s def equalSubstrings(s): # Length of the string n = len (s) # Prefix arrays for 0s and 1s pre0 = [ 0 ] * n pre1 = [ 0 ] * n # If character at index 0 is 0 if (s[ 0 ] = = '0' ): pre0[ 0 ] = 1 # If character at index 0 is 1 else : pre1[ 0 ] = 1 # Filling the prefix arrays for i in range ( 1 , n): if (s[i] = = '0' ): pre0[i] = pre0[i - 1 ] + 1 pre1[i] = pre1[i - 1 ] else : pre0[i] = pre0[i - 1 ] pre1[i] = pre1[i - 1 ] + 1 # Vector to store the answer ans = [] # Map to store the ratio mp = {} for i in range (n): # Find the gcd of pre0[i] and pre1[i] x = __gcd(pre0[i], pre1[i]) # Converting the elements in # simplest form l = pre0[i] / / x r = pre1[i] / / x # Update the value in map if (f '[{l}, {r}]' in mp): mp[f '[{l}, {r}]' ] + = 1 else : mp[f '[{l}, {r}]' ] = 1 # Store this in ans ans.append(mp[f '[{l}, {r}]' ]) # Return the ans vector for i in ans: print (i, end = " " ) # Driver Code s = "001110" equalSubstrings(s) # This code is contributed by gfgking |
C#
// C# program for the above approach using System; using System.Collections.Generic; class GFG { // Function to retuan a prefix array of // equal partitions of the given string // consisting of 0s and 1s public static void equalSubstrings( string s) { // Length of the string int n = s.Length; // Prefix arrays for 0s and 1s int [] pre0 = new int [n]; int [] pre1 = new int [n]; // Arrays.fill(pre0, 0); // Arrays.fill(pre1, 0); // If character at index 0 is 0 if (s[0] == '0' ) { pre0[0] = 1; } // If character at index 0 is 1 else { pre1[0] = 1; } // Filling the prefix arrays for ( int i = 1; i < n; i++) { if (s[i] == '0' ) { pre0[i] = pre0[i - 1] + 1; pre1[i] = pre1[i - 1]; } else { pre0[i] = pre0[i - 1]; pre1[i] = pre1[i - 1] + 1; } } // Vector to store the answer List< int > ans = new List< int >(); // Map to store the ratio Dictionary< string , int > mp = new Dictionary< string , int >(); for ( int i = 0; i < n; i++) { // Find the gcd of pre0[i] and pre1[i] int x = __gcd(pre0[i], pre1[i]); // Converting the elements in // simplest form int l = pre0[i] / x, r = pre1[i] / x; string key = l + "," + r; // Update the value in map if (mp.ContainsKey(key)) mp[key] += 1; else mp[key] = 1; // Store this in ans ans.Add(mp[key]); } // Return the ans vector foreach ( int i in ans) Console.Write(i + " " ); } public static int __gcd( int a, int b) { if (b == 0) return a; return __gcd(b, a % b); } // Driver Code public static void Main( string [] args) { string s = "001110" ; equalSubstrings(s); } } // This code is contributed by ukasp. |
Javascript
<script> // JavaScript program for the above approach const __gcd = (a, b) => { if (b == 0) return a; return __gcd(b, a % b) } // Function to retuan a prefix array of // equal partitions of the given string // consisting of 0s and 1s const equalSubstrings = (s) => { // Length of the string let n = s.length; // Prefix arrays for 0s and 1s let pre0 = new Array(n).fill(0); let pre1 = new Array(n).fill(0); // If character at index 0 is 0 if (s[0] == '0' ) { pre0[0] = 1; } // If character at index 0 is 1 else { pre1[0] = 1; } // Filling the prefix arrays for (let i = 1; i < n; i++) { if (s[i] == '0' ) { pre0[i] = pre0[i - 1] + 1; pre1[i] = pre1[i - 1]; } else { pre0[i] = pre0[i - 1]; pre1[i] = pre1[i - 1] + 1; } } // Vector to store the answer ans = []; // Map to store the ratio mp = {}; for (let i = 0; i < n; i++) { // Find the gcd of pre0[i] and pre1[i] let x = __gcd(pre0[i], pre1[i]); // Converting the elements in // simplest form let l = pre0[i] / x, r = pre1[i] / x; // Update the value in map if ([l, r] in mp) mp[[l, r]] += 1 else mp[[l, r]] = 1 // Store this in ans ans.push(mp[[l, r]]); } // Return the ans vector for (let i in ans) document.write(`${ans[i]} `); } // Driver Code let s = "001110" ; equalSubstrings(s); // This code is contributed by rakeshsahni </script> |
Output
1 2 1 1 1 2
Time Complexity: O(nlogn)
Auxiliary Space: O(n)
Please Login to comment...