
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Count Substrings with 0s and 1s in Ratio of x:y
In this problem, we will count substrings of the given binary string containing the number of ?0' and ?1' characters in the X : Y ratio.
The naïve approach finds all substrings of the given binary string, counts ?0' and ?1', and checks whether the counts are in the X : Y ratio. The efficient approach uses the prefix sum technique to solve the problem.
Problem statement ? We have given a binary string of length bin_len. We need to count substrings having a number of 0s and 1s in the ratio of X : Y.
Sample examples
Input
bin_str = "00111001100"; X = 2; Y = 3;
Output
5
Explanation ? The substrings having ?1' and ?0' in the 2 : 3 ratio are 00111, 01110, 10011, 11001, and 11100.
Input
bin_str = "11111"; X = 2; Y = 3;
Output
0
Explanation ? The binary string contains only ?1'. So, it is not possible to find a substring containing the ?0' and ?1' in the 2 : 3 ratio.
Input
bin_str = "00100"; X = 2; Y = 1;
Output
3
Explanation ? We can take the 001, 010, and 100 substrings.
Approach 1
In this approach, we will use two nested loops to find all substrings of the binary string. After that, we will count the number of ?1' and ?0' in the binary string.
If the below condition is true for any substring, we can consider the substring in the answer.
zeroCnt * Y == oneCnt * X
Algorithm
Step 1 ? Initialize the ?ans' with 0 to store the count of substrings.
Step 2 ? Start traversing the binary string using the for loop. Also, use another loop to get each substring starting from the current index.
Step 3 ? Use the substr() method to get the substring of the particular length.
Step 4 ? Initialize the ?zeroCnt' and ?oneCnt' with 0 to store the count of ?1' and ?0' in the substring.
Step 5 ? Use the third nested loop to count ?1' and ?0'. If the current character is ?1', increment ?oneCnt'. Otherwise, increment the ?ZeroCnt'.
Step 6 ? In the second nested loop, if zeroCnt * Y == oneCnt * X is true, increment the ?ans' value by 1.
Step 7 ? At last, return the ?ans' value from the function.
Example
#include <bits/stdc++.h> using namespace std; int subStrCnt(string &bin_str, int X, int Y) { int ans = 0; // Get all substrings of the binary string for (int p = 0; p < bin_str.length(); p++) { for (int q = 1; q <= bin_str.length() - p; q++) { string sub_str = bin_str.substr(p, q); // Counting the number of zeros and ones in the substring int zeroCnt = 0, oneCnt = 0; for (int p = 0; p < sub_str.length(); p++) { if (sub_str[p] == '0') zeroCnt++; else oneCnt++; } // Checking whether the count of zeros and ones in the X:Y ratio if (zeroCnt * Y == oneCnt * X) ans++; } } return ans; } int main() { string bin_str = "00111001100"; int X = 2; int Y = 3; cout << "The total substrings having 0's and 1's in the ratio X:Y is " << subStrCnt(bin_str, X, Y); return 0; }
Output
The total substrings having 0's and 1's in the ratio X:Y is 5
Time complexity ? O(N*N*N), where O(N*N) is to get all substrings and O(N) is to count ?1' and ?0' in the substring.
Space complexity ? O(N) to store the substring.
Approach 2
We will consider the ?0' as ?Y and ?1' as ?X in this approach. We will find the sum of ?Y and X according to the ?0' and ?1' numbers. If the sum is equal to 0, we can say that we found the valid substring.
Also, we will use the map data structure to store the prefix sum. Whenever we find any prefix sum value for a second time, we can take the substring between the indexes where the sum is 0.
For example, the binary string is "00111001100". We find the same prefix sum at the 0th and 5th index. So, we can take substring starting from the 1st index to the 5th index.
Algorithm
Step 1 ? Initialize the ?binary' list to convert the binary string in the ?Y and X format.
Step 2 ? Traverse the string. If the current character is ?0', insert the ??Y' in the list. Otherwise, insert the ?X' in the list.
Step 3 ? Define the ?pref' map to store the prefix sum as a key and the number of occurrences of its value.
Step 4 ? Also, initialize the ?ans' to store the count of substrings and ?sum' with 0 to store the prefix sum.
Step 5 ? Start traversing the string. Add binary[p] to the sum.
Step 6 ? If ?sum' is 0, increment the ?ans' by 1.
Step 7 ? If the sum key exists in the map, add its value to the ?ans'.
Step 8 ? Increment the pref[sum] by 1.
Step 9 ? Return the ?ans' value.
Example
#include <bits/stdc++.h> using namespace std; int subStrCnt(string &bin_str, int X, int Y) { vector<int> binary; for (auto ch : bin_str) { if (ch == '0') { // Change '0' to -Y binary.push_back(-Y); } else { // Change '1' to X binary.push_back(X); } } // To store prefix sum unordered_map<int, int> pref; int ans = 0; int sum = 0; // Traverse string for (int p = 0; p < binary.size(); p++) { // Add a current element to sum sum += binary[p]; // When aX - bY = 0, we found the substring if (sum == 0) ans += 1; // When prefix sum exists, we add the value to ans if (pref.find(sum) != pref.end()) ans += pref[sum]; // Increment the count of prefix sum pref[sum] += 1; } return ans; } int main() { string bin_str = "00111001100"; int X = 2; int Y = 3; cout << "The total substrings having 0's and 1's in the ratio X:Y is " << subStrCnt(bin_str, X, Y); return 0; }
Output
The total substrings having 0's and 1's in the ratio X:Y is 5
Time complexity ? O(N) for finding the prefix sum.
Space complexity ? O(N) to store the prefix sum in the map.
The optimized approach efficiently solves the problem, taking only O(N) times. However, it can take more space for the large size of the binary string. Programmers may try to solve the problem to find the substring having an equal number of ?0' and ?1' in the binary string.