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:
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>
Time Complexity: O(nlogn)
Auxiliary Space: O(n)
Similar Reads
Count of substrings that start and end with 1 in given Binary String Given a binary string, count the number of substrings that start and end with 1. Examples: Input: "00100101"Output: 3Explanation: three substrings are "1001", "100101" and "101" Input: "1001"Output: 1Explanation: one substring "1001" Recommended PracticeCount SubstringsTry It!Count of substrings tha
12 min read
Split the binary string into substrings with equal number of 0s and 1s Given a binary string str of length N, the task is to find the maximum count of consecutive substrings str can be divided into such that all the substrings are balanced i.e. they have equal number of 0s and 1s. If it is not possible to split str satisfying the conditions then print -1.Example: Input
8 min read
Count of substrings in a Binary String that contains more 1s than 0s Given a binary string s, the task is to calculate the number of such substrings where the count of 1's is strictly greater than the count of 0's. Examples Input: S = "110011"Output: 11Explanation: Substrings in which the count of 1's is strictly greater than the count of 0's are { S[0]}, {S[0], S[1]
15+ min read
Check if all substrings of length K of a Binary String has equal count of 0s and 1s Given a binary string S of length N and an even integer K, the task is to check if all substrings of length K contains an equal number of 0s and 1s. If found to be true, print âYesâ. Otherwise, print âNoâ. Examples: Input: S = "101010", K = 2Output: YesExplanation:Since all the substrings of length
6 min read
Count of non-overlapping sub-strings "101" and "010" in the given binary string Given binary string str, the task is to find the count of non-overlapping sub-strings of either the form "010" or "101". Examples: Input: str = "10101010101" Output: 3 str[0..2] = "101" str[3..5] = "010" str[6..8] = "101"Input: str = "111111111111110" Output: 0 Approach: Initialize count = 0 and for
5 min read