# Count of substrings with equal ratios of 0s and 1s till ith index in given Binary String

• Last Updated : 23 Nov, 2021

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:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

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:

1. Create two prefix arrays for occurrences of 0s and 1s say pre0[] and pre1[] respectively.
2. 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.
3. 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 ``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, ``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 ans = ``new` `ArrayList();` `        ``// Map to store the ratio``        ``HashMap mp = ``new` `HashMap();` `        ``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

 ``
Output
`1 2 1 1 1 2 `

Time Complexity: O(nlogn)
Auxiliary Space: O(n)

My Personal Notes arrow_drop_up