Count Substrings that can be Made of Length 1 by Replacing "01" or "10" with 1 or 0


In this problem, we will count substrings that we can make of length 1 by replacing the β€˜10’ and β€˜01’ substrings with β€˜1’ or β€˜0’ characters.

When any binary string contains an equal number of β€˜0’ and β€˜1’, we can always make it of length 1 by performing the replacement operations. So, the problem is solved by finding the substrings with equal numbers of β€˜0’ and β€˜1’.

Problem statement βˆ’ We have given a binary string named bin_str and of length bin_len. We need to count the total number of substrings that we can make of length 1 by changing β€˜10’ or β€˜01’ to either β€˜1’ or β€˜0’.

Sample examples

Input

bin_str = "01010";

Output

6

Explanation βˆ’ The substrings are 01, 01, 0101, 10, 10, and 1010.

Input

bin_str = "01";

Output

1

Explanation βˆ’ We can replace 01 with β€˜1’ or β€˜0’ to make it of length 1.

Input

bin_str = "00000";

Output

0

Explanation βˆ’ No substring exists, which we can make of length 1 after replacement.

Approach 1

The problem can be solved by counting the number of substrings having equal numbers of β€˜1’ and β€˜0.’ We will find all substrings of the string and count β€˜1’ and β€˜0’ in the string. If the count of β€˜1’ and β€˜0’ are the same, we will increment the β€˜ans’ by 1.

Algorithm

Step 1 βˆ’ Initialize the β€˜cnt’ with 0 to store the number of valid substrings.

Step 2 βˆ’ Also, initialize the β€˜cnt0’ and β€˜cnt1’ with 0 to store the count of β€˜1’ and β€˜0’.

Step 3 βˆ’ Start traversing the binary string.

Step 4 βˆ’ Use a nested loop to traverse from index p to the last index.

Step 5 βˆ’ If the current character is β€˜0’, increment β€˜cnt0’ by 1. Otherwise, increment β€˜cnt1’ by 1.

Step 6 βˆ’ If cnt0 and cnt1 are equal, increment the β€˜cnt’ value by 1.

Step 7 βˆ’ Return the β€˜cnt’ value.

Example

#include <bits/stdc++.h>
using namespace std;

int totalSubstrs(string &bin_str, int &bin_len) {
    // To store a number of valid substrings
    int cnt = 0;
    // Couting number of substrings having equal 1's and 0's
    for (int p = 0; p < bin_len; p++) {
        // To store count of 1's and 0's in substring
        int cnt0 = 0, cnt1 = 0;
        for (int q = p; q < bin_len; q++) {
            if (bin_str[q] == '0') {
                cnt0++;
            } else {
                cnt1++;
            }
            // When the substring has an equal number of 0's and 1's
            if (cnt0 == cnt1) {
                cnt++;
            }
        }
    }
    return cnt;
}
int main() {
    string bin_str = "01010";
    int bin_len = bin_str.length();
    cout << "The number of substrings according to the given problem statement is " << totalSubstrs(bin_str, bin_len);
    return 0;
}

Output

The number of substrings according to the given problem statement is 6

Time complexity βˆ’ O(N*N) to traverse all substrings of the binary string.

Space complexity βˆ’ O(1), as we don’t use any extra space.

Approach 2

In this approach, we will use the prefix sum technique to count the number of substrings having equal numbers of β€˜1’ and β€˜0’. We will keep track of the difference of the count of β€˜1’ and β€˜0’ at every index.

If any two index difference of count of β€˜1’ and β€˜0’ is the same, we can take the substring between both indices.

Algorithm

Step 1 βˆ’ Initialize the β€˜cnt’ and β€˜diff’ with 0 to store the count of valid substrings and the difference of count of β€˜1’ and β€˜0’.

Step 2 βˆ’ Also, initialize the β€˜prefixSum’ list with 0 to store the difference.

Step 3 βˆ’ Start traversing the string. If the current character is β€˜0’, increment the β€˜diff’ value by 1. Otherwise, decrement the β€˜diff’ value by β€˜1’.

Step 4 βˆ’ If β€˜diff’ is β€˜0’, increment the β€˜cnt’ by 1.

Step 5 βˆ’ If the value in the β€˜prefixSum’ array at the β€˜diff’ index is greater than 0, add prefixSum[diff] to the β€˜cnt’.

Step 6 βˆ’ Increment the value of the β€˜prefixSum’ list at the β€˜diff’ index by 1.

Step 7 βˆ’ Return the β€˜cnt’ value.

Example

#include <iostream>
#include <vector>
using namespace std;

int totalSubstrs(string bin_str, int bin_len) {
    int cnt = 0;
    int diff = 0; // To store the difference of count of 1's and 0's
    vector<int> prefixSum(bin_len, 0); 
    for (char ch : bin_str) {
        // For the '0' character
        if (ch == '0') {
            diff++;
        } else if (ch == '1') {
            // For '1' character
            diff--;
        }
        if (diff == 0) {
            // When the number of '0' and '1' are equal
            cnt++;
        }
        if (prefixSum[diff] > 0) {
            cnt += prefixSum[diff];
        }
        prefixSum[diff]++;
    }
    return cnt;
}
int main() {
    string bin_str = "01010";
    int bin_len = bin_str.length();
    cout << "The number of substrings according to the given problem statement is - " << totalSubstrs(bin_str, bin_len);
    return 0;
}

Output

The number of substrings according to the given problem statement is 6

Time complexity βˆ’ O(N) to get the prefix sum of the difference of count of β€˜1’ and β€˜0’.

Space complexity βˆ’ O(N) to store the difference in the prefix sum list.

The problem is similar to finding the substrings with equal numbers of β€˜1’ and β€˜0’. We have also used the prefix sum technique to solve the problem by storing the difference of the count of β€˜1’ and β€˜0’ in the prefix array. The second approach is time optimized, but it may take more memory for larger binary strings.

Updated on: 17-Jul-2023

34 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements