Count ways to split a Binary String into three substrings having equal count of zeros
Last Updated :
14 Jun, 2021
Given binary string str, the task is to count the total number of ways to split the given string into three non-overlapping substrings having the same number of 0s.
Examples:
Input: str = "01010"
Output: 4
Explanation:
The possible splits are: [0, 10, 10], [01, 01, 0], [01, 0, 10], [0, 101, 0]
Input: str = "11111"
Output: 0
Approach: To solve the problem, the idea is to use the concept of Hashing. Below are the steps to solve the problem:
- Iterate over the string and count the total number of zeros and store it in a variable, say total_count.
- Use a Hashmap, say map, to store the frequency of cumulative sum of 0s.
- Initialize a variable k with total_count/3 which denotes the number of 0 required in each partition.
- Initialize variables res and sum to store the number of ways to split the string and cumulative sum of 0s respectively.
- Iterate over the given string and increment sum, if the current character is 0.
- Increment res by map[k], if sum = 2k and k exist on the map.
- Update the frequency of the sum in the map.
- Return res at the end.
- Return 0, if total_count is not divisible by 3.
Below is the implementation of the above approach:
C++
// C++ implementation for the above approach
#include<bits/stdc++.h>
using namespace std;
// Function to return ways to split
// a string into three parts
// with the equal number of 0
int count(string s)
{
// Store total count of 0s
int cnt = 0;
// Count total no. of 0s
// character in given string
for(char c : s)
{
cnt += c == '0' ? 1 : 0;
}
// If total count of 0
// character is not
// divisible by 3
if (cnt % 3 != 0)
return 0;
int res = 0, k = cnt / 3, sum = 0;
// Initialize mp to store
// frequency of k
map<int, int> mp;
// Traverse string to find
// ways to split string
for(int i = 0; i < s.length(); i++)
{
// Increment count if 0 appears
sum += s[i] == '0' ? 1 : 0;
// Increment result if sum equal to
// 2*k and k exists in mp
if (sum == 2 * k && mp.find(k) != mp.end() &&
i < s.length() - 1 && i > 0)
{
res += mp[k];
}
// Insert sum in mp
mp[sum]++;
}
// Return result
return res;
}
// Driver Code
int main()
{
// Given string
string str = "01010";
// Function call
cout << count(str);
}
// This code is contributed by rutvik_56
Java
// Java implementation for the above approach
import java.util.*;
import java.lang.*;
class GFG {
// Function to return ways to split
// a string into three parts
// with the equal number of 0
static int count(String s)
{
// Store total count of 0s
int cnt = 0;
// Count total no. of 0s
// character in given string
for (char c : s.toCharArray()) {
cnt += c == '0' ? 1 : 0;
}
// If total count of 0
// character is not
// divisible by 3
if (cnt % 3 != 0)
return 0;
int res = 0, k = cnt / 3, sum = 0;
// Initialize map to store
// frequency of k
Map<Integer, Integer> map = new HashMap<>();
// Traverse string to find
// ways to split string
for (int i = 0; i < s.length(); i++) {
// Increment count if 0 appears
sum += s.charAt(i) == '0' ? 1 : 0;
// Increment result if sum equal to
// 2*k and k exists in map
if (sum == 2 * k && map.containsKey(k)
&& i < s.length() - 1 && i > 0) {
res += map.get(k);
}
// Insert sum in map
map.put(sum,
map.getOrDefault(sum, 0) + 1);
}
// Return result
return res;
}
// Driver Code
public static void main(String[] args)
{
// Given string
String str = "01010";
// Function call
System.out.println(count(str));
}
}
Python3
# Python3 implementation for
# the above approach
# Function to return ways to split
# a string into three parts
# with the equal number of 0
def count(s):
# Store total count of 0s
cnt = 0
# Count total no. of 0s
# character in given string
for c in s:
if c == '0':
cnt += 1
# If total count of 0
# character is not
# divisible by 3
if (cnt % 3 != 0):
return 0
res = 0
k = cnt // 3
sum = 0
# Initialize map to store
# frequency of k
mp = {}
# Traverse string to find
# ways to split string
for i in range(len(s)):
# Increment count if 0 appears
if s[i] == '0':
sum += 1
# Increment result if sum equal to
# 2*k and k exists in map
if (sum == 2 * k and k in mp and
i < len(s) - 1 and i > 0):
res += mp[k]
# Insert sum in map
if sum in mp:
mp[sum] += 1
else:
mp[sum] = 1
# Return result
return res
# Driver Code
if __name__ == "__main__":
# Given string
st = "01010"
# Function call
print(count(st))
# This code is contributed by Chitranayal
C#
// C# implementation for the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to return ways to split
// a string into three parts
// with the equal number of 0
static int count(String s)
{
// Store total count of 0s
int cnt = 0;
// Count total no. of 0s
// character in given string
foreach(char c in s.ToCharArray())
{
cnt += c == '0' ? 1 : 0;
}
// If total count of 0
// character is not
// divisible by 3
if (cnt % 3 != 0)
return 0;
int res = 0, k = cnt / 3, sum = 0;
// Initialize map to store
// frequency of k
Dictionary<int,
int> map = new Dictionary<int,
int>();
// Traverse string to find
// ways to split string
for(int i = 0; i < s.Length; i++)
{
// Increment count if 0 appears
sum += s[i] == '0' ? 1 : 0;
// Increment result if sum equal to
// 2*k and k exists in map
if (sum == 2 * k && map.ContainsKey(k) &&
i < s.Length - 1 && i > 0)
{
res += map[k];
}
// Insert sum in map
if(map.ContainsKey(sum))
map[sum] = map[sum] + 1;
else
map.Add(sum, 1);
}
// Return result
return res;
}
// Driver Code
public static void Main(String[] args)
{
// Given string
String str = "01010";
// Function call
Console.WriteLine(count(str));
}
}
// This code is contributed by Amit Katiyar
JavaScript
<script>
// Javascript implementation for the above approach
// Function to return ways to split
// a string into three parts
// with the equal number of 0
function count(s)
{
// Store total count of 0s
var cnt = 0;
// Count total no. of 0s
// character in given string
s.split('').forEach(c => {
cnt += (c == '0') ? 1 : 0;
});
// If total count of 0
// character is not
// divisible by 3
if (cnt % 3 != 0)
return 0;
var res = 0, k = parseInt(cnt / 3), sum = 0;
// Initialize mp to store
// frequency of k
var mp = new Map();
// Traverse string to find
// ways to split string
for(var i = 0; i < s.length; i++)
{
// Increment count if 0 appears
sum += (s[i] == '0') ? 1 : 0;
// Increment result if sum equal to
// 2*k and k exists in mp
if (sum == 2 * k && mp.has(k) &&
i < s.length - 1 && i > 0)
{
res += mp.get(k);
}
// Insert sum in mp
if(mp.has(sum))
mp.set(sum, mp.get(sum)+1)
else
mp.set(sum, 1);
}
// Return result
return res;
}
// Driver Code
// Given string
var str = "01010";
// Function call
document.write( count(str));
</script>
Time Complexity: O(N)
Auxiliary Space: O(N)
EFFICIENT APPROACH:
In order to split the input string into three parts, only two cuts are needed, which will give three substrings-S1, S2, and S3. Each substring will have an equal number of 0's and that will be (total number of 0's)/3. Now keep track of the count of the number of 0's from the beginning of the string. Once the count is equal to (total number of 0's)/3, make the first cut. Similarly, make the second cut once the count of 0's equals 2*(total number of 1's)/3.
Algorithm
- Count the number of 0's. If not divisible by 3, then answer=0.
- If the count is 0 then each substring will have an equal number of '0's i.e. zero number of '0's. Therefore, the total number of ways to split the given string is the number of combinations of selecting 2 places to split the string out of n-1 places. For the first selection, we have n-1 choices and for the second selection, we have n-2 choices. Hence, the total number of combinations is (n-1)*(n-2). Since the selections are identical, therefore divide it by factorial of 2. So answer= ((n-1)*(n-2))/2.
- Traverse the given string from the beginning and keeping count of the number of '0s' again, if the count reaches the (total number of '0s')/3, we begin to accumulate the number of the ways of the 1st cut; when the count reaches the 2*(total number of '0s')/3, we start to accumulate the number of the ways of the 2nd cut.
- The answer is the multiplication of the number of ways of the 1st cut and 2nd cut.
Below is the implementation of the above approach:
C++
// C++ program for above approach
#include <bits/stdc++.h>
using namespace std;
// Function to calculate
// the number of ways to split
int splitstring(string s)
{
int n = s.length();
// Calculating the total
// number of zeros
int zeros = 0;
for (int i = 0; i < n; i++)
if (s[i] == '0')
zeros++;
// Case1
// If total count of zeros is not
// divisible by 3
if (zeros % 3 != 0)
return 0;
// Case2
// if total count of zeros
// is zero
if (zeros == 0)
return ((n - 1) * (n - 2)) / 2;
// Case3
// General case
// Number of zeros in each substring
int zerosInEachSubstring = zeros / 3;
// Initialising zero to the number of ways
// for first and second cut
int waysOfFirstCut = 0, waysOfSecondCut = 0;
// Initializing the count
int count = 0;
// Traversing from the beginning
for (int i = 0; i < n; i++)
{
// Incrementing the count
// if the element is '0'
if (s[i] == '0')
count++;
// Incrementing the ways for the
// 1st cut if count is equal to
// zeros required in each substring
if (count == zerosInEachSubstring)
waysOfFirstCut++;
// Incrementing the ways for the
// 2nd cut if count is equal to
// 2*(zeros required in each substring)
else if (count == 2 * zerosInEachSubstring)
waysOfSecondCut++;
}
// Total number of ways to split is
// multiplication of ways for the 1st
// and 2nd cut
return waysOfFirstCut * waysOfSecondCut;
}
// Driver Code
int main()
{
string s = "01010";
// Function Call
cout << "The number of ways to split is "
<< splitstring(s) << endl;
}
// this code is contributed by Arif
Java
// Java program for above approach
import java.util.*;
class GFG{
// Function to calculate
// the number of ways to split
static int splitstring(String s)
{
int n = s.length();
// Calculating the total
// number of zeros
int zeros = 0;
for(int i = 0; i < n; i++)
if (s.charAt(i) == '0')
zeros++;
// Case1
// If total count of zeros is not
// divisible by 3
if (zeros % 3 != 0)
return 0;
// Case2
// if total count of zeros
// is zero
if (zeros == 0)
return ((n - 1) * (n - 2)) / 2;
// Case3
// General case
// Number of zeros in each substring
int zerosInEachSubstring = zeros / 3;
// Initialising zero to the number of ways
// for first and second cut
int waysOfFirstCut = 0;
int waysOfSecondCut = 0;
// Initializing the count
int count = 0;
// Traversing from the beginning
for(int i = 0; i < n; i++)
{
// Incrementing the count
// if the element is '0'
if (s.charAt(i) == '0')
count++;
// Incrementing the ways for the
// 1st cut if count is equal to
// zeros required in each substring
if (count == zerosInEachSubstring)
waysOfFirstCut++;
// Incrementing the ways for the
// 2nd cut if count is equal to
// 2*(zeros required in each substring)
else if (count == 2 * zerosInEachSubstring)
waysOfSecondCut++;
}
// Total number of ways to split is
// multiplication of ways for the 1st
// and 2nd cut
return waysOfFirstCut * waysOfSecondCut;
}
// Driver Code
public static void main(String args[])
{
String s = "01010";
// Function Call
System.out.println("The number of " +
"ways to split is " +
splitstring(s));
}
}
// This code is contributed by Stream_Cipher
Python3
# Python3 program for above approach
# Function to calculate
# the number of ways to split
def splitstring(s):
n = len(s)
# Calculating the total
# number of zeros
zeros = 0
for i in range(n):
if s[i] == '0':
zeros += 1
# Case1
# If total count of zeros is not
# divisible by 3
if zeros % 3 != 0:
return 0
# Case2
# if total count of zeros
# is zero
if zeros == 0:
return ((n - 1) *
(n - 2)) // 2
# Case3
# General case
# Number of zeros in each substring
zerosInEachSubstring = zeros // 3
# Initialising zero to the number of ways
# for first and second cut
waysOfFirstCut, waysOfSecondCut = 0, 0
# Initializing the count
count = 0
# Traversing from the beginning
for i in range(n):
# Incrementing the count
# if the element is '0'
if s[i] == '0':
count += 1
# Incrementing the ways for the
# 1st cut if count is equal to
# zeros required in each substring
if (count == zerosInEachSubstring):
waysOfFirstCut += 1
# Incrementing the ways for the
# 2nd cut if count is equal to
# 2*(zeros required in each substring)
elif (count == 2 * zerosInEachSubstring):
waysOfSecondCut += 1
# Total number of ways to split is
# multiplication of ways for the 1st
# and 2nd cut
return waysOfFirstCut * waysOfSecondCut
# Driver code
s = "01010"
# Function call
print("The number of ways to split is", splitstring(s))
# This code is contributed by divyeshrabadiya07
C#
// C# program for above approach
using System.Collections.Generic;
using System;
class GFG{
// Function to calculate
// the number of ways to split
static int splitstring(string s)
{
int n = s.Length;
// Calculating the total
// number of zeros
int zeros = 0;
for(int i = 0; i < n; i++)
if (s[i] == '0')
zeros++;
// Case1
// If total count of zeros is not
// divisible by 3
if (zeros % 3 != 0)
return 0;
// Case2
// if total count of zeros
// is zero
if (zeros == 0)
return ((n - 1) * (n - 2)) / 2;
// Case3
// General case
// Number of zeros in each substring
int zerosInEachSubstring = zeros / 3;
// Initialising zero to the number of ways
// for first and second cut
int waysOfFirstCut = 0;
int waysOfSecondCut = 0;
// Initializing the count
int count = 0;
// Traversing from the beginning
for(int i = 0; i < n; i++)
{
// Incrementing the count
// if the element is '0'
if (s[i] == '0')
count++;
// Incrementing the ways for the
// 1st cut if count is equal to
// zeros required in each substring
if (count == zerosInEachSubstring)
waysOfFirstCut++;
// Incrementing the ways for the
// 2nd cut if count is equal to
// 2*(zeros required in each substring)
else if (count == 2 * zerosInEachSubstring)
waysOfSecondCut++;
}
// Total number of ways to split is
// multiplication of ways for the 1st
// and 2nd cut
return waysOfFirstCut * waysOfSecondCut;
}
// Driver Code
public static void Main()
{
string s = "01010";
// Function call
Console.WriteLine("The number of ways " +
"to split is " +
splitstring(s));
}
}
// This code is contributed by Stream_Cipher
JavaScript
<script>
// Javascript program for above approach
// Function to calculate
// the number of ways to split
function splitstring(s)
{
let n = s.length;
// Calculating the total
// number of zeros
let zeros = 0;
for(let i = 0; i < n; i++)
if (s[i] == '0')
zeros++;
// Case1
// If total count of zeros is not
// divisible by 3
if (zeros % 3 != 0)
return 0;
// Case2
// if total count of zeros
// is zero
if (zeros == 0)
return parseInt(((n - 1) * (n - 2)) / 2, 10);
// Case3
// General case
// Number of zeros in each substring
let zerosInEachSubstring = parseInt(zeros / 3, 10);
// Initialising zero to the number of ways
// for first and second cut
let waysOfFirstCut = 0;
let waysOfSecondCut = 0;
// Initializing the count
let count = 0;
// Traversing from the beginning
for(let i = 0; i < n; i++)
{
// Incrementing the count
// if the element is '0'
if (s[i] == '0')
count++;
// Incrementing the ways for the
// 1st cut if count is equal to
// zeros required in each substring
if (count == zerosInEachSubstring)
waysOfFirstCut++;
// Incrementing the ways for the
// 2nd cut if count is equal to
// 2*(zeros required in each substring)
else if (count == 2 * zerosInEachSubstring)
waysOfSecondCut++;
}
// Total number of ways to split is
// multiplication of ways for the 1st
// and 2nd cut
return waysOfFirstCut * waysOfSecondCut;
}
let s = "01010";
// Function call
document.write("The number of ways " +
"to split is " +
splitstring(s));
</script>
OutputThe number of ways to split is 4
Time Complexity: O(n)
Space Complexity: O(1)
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
Count of binary strings of length N having equal count of 0's and 1's
Given an integer N, the task is to find the number of binary strings possible of length N having same frequency of 0s and 1s. If such string is possible of length N, print -1. Note: Since the count can be very large, return the answer modulo 109+7.Examples: Input: N = 2 Output: 2 Explanation: All po
6 min read
Split Strings into two Substrings whose distinct element counts are equal
Given a string S of length N, the task is to check if a string can be split into two non-intersecting strings such that the number of distinct characters are equal in both. Examples: Input: N = 6, S = "abccba"Output: TrueExplanation: Splitting two strings as "abc" and "cba" has 3 distinct characters
8 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 ways to partition a Binary String such that each substring contains exactly two 0s
Given binary string str, the task is to find the count of ways to partition the string such that each partitioned substring contains exactly two 0s. Examples: Input: str = "00100" Output: 2Explanation: Possible ways to partition the string such that each partition contains exactly two 0s are: { {"00
6 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
Count ways to generate Binary String not containing "0100" Substring
Given the number N, count the number of ways to create a binary string (the string that contains characters as zero or one) of size N such that it does not contain "0100" as a substring. A substring is a contiguous sequence of characters within a string. Examples: Input: N = 4Output: 15Explanation:
15+ min read
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 substrin
9 min read
Minimize replacement of bits to make the count of 01 substring equal to 10 substring
Given a binary string str. The task is to minimize the number of replacements of '0' by '1' or '1' by '0' to balance the binary string. A binary string is said to be balanced: "if the number of "01" substring = number of "10" substring". Examples: Input: str = "101010" Output: 1Explanation: "01" = 2
4 min read
Counting even decimal value substrings in a binary string
Given a binary string of size N. Count all substring that have even decimal value considering binary to decimal conversion from left to right (For example a substring "1011" is treated as 13) Examples : Input : 101Output : 2Explanation : Substring are : 1, 10, 101, 0, 01, 1 In decimal form : 1, 1, 3
9 min read