Find all substrings with even 1s whose reverse is also present in given String


In this problem, we need to prepare a set of unique substrings of the given binary string and remove them from the set if it contains an even number of 1s and its reverse also exits in the set.

We can solve the problem using two ways. The first way is to find all substrings of the given binary string, check if any substring contains an even number of 1's and its reverse exits, and remove the reverse string from the set.

Another way is by comparing the total number of parity bits in the given string.

Problem statement - We have given binary string str containing the even number of 1's. We need to prepare a set of all unique substrings of the given binary strings. After that, we need to consider the substring of length n from the set containing an even number of 1s. If the reverse of the substring also exists in the set, remove the reverse substring from the set. In the output, print the size of the set containing unique substrings.

Sample examples

Input

str = "01010"

Output

8

Explanation

  • The set of unique substrings is [0, 1, 01, 010, 0101, 01010, 10, 101, 1010]. It contains total 9 substrings.

  • The 0101 contains the even number of 1s, and its reverse also exists in the set. So, we will remove its reverse, which is 1010, from the given set.

  • The final set will be [0, 1, 01, 010, 0101, 01010, 10, 101]. The size of the final set is 8.

Input

str = '1010'

Output

7

Explanation

  • Unique substrings are [ 1, 10, 101, 1010, 0, 01, 010].

  • For any string containing an even number of 1's, its reverse is not exist in the set. So, we don't need to remove any string from the set.

  • The final output is the same as the original set's size.

Input

str = "111"

Output

3

  • Unique substrings are [1, 11, 111].

  • The string containing an even number of 1's is only 11.

  • The reverse of 11 is also 11. So, we don't need to remove it from the set, and the answer is 3.

Approach 1

In this approach, we will create a set of all unique substrings of the given binary string. After that, we will traverse the set, and if we find any string containing an even number of 1's and its reverse also exists in the set, we will remove the string from the set.

Algorithm

Step 1 - Define the set named 'subStrings' to store unique substrings.

Step 2 - Start traversing the string from the 0th index. Inside the loop, define the 'temp' variable and initialize with an empty string.

Step 3 - Use another nested loop starting iterations from the pth index, and keep appending the qth character to the 'temp' string.

Step 4 - Insert the 'temp' string into the set.

Step 5 - Use the iterator to traverse the set of substrings.

Step 7 - If a total number of 1's are even in the current string, reverse the temp string, and check for the existence of the reverse temp in the set.

Step 8 - If a reverse string exists, remove the reverse string.

Step 9 - Return the size of the set.

Example

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

int getSize(string str) {
   //  unordered set to store all substrings of a given string
   unordered_set<string> subStrings;
   // finding all substrings of a given string
   for (int p = 0; p < str.length(); p++) {
      string temp = "";
      for (int q = p; q < str.length(); q++) {
         temp += str[q];
         subStrings.insert(temp);
      }
   }
   // Check if any string contains an even number of 1's and its reverse exists in the set, then remove the string.
   for (auto it = subStrings.begin(); it != subStrings.end(); it++) {
      string temp = *it;
      // count the number of 1's in the string
      int cnt1s = 0;
      for (int i = 0; i < temp.length(); i++) {
         if (temp[i] == '1')
            cnt1s++;
      }
      // If count of 1's is even
      if (cnt1s % 2 == 0) {
         // reverse substring
         reverse(temp.begin(), temp.end());
         // check if reverse exists in the set, remove it.
         if (temp != *it && subStrings.find(temp) != subStrings.end()) {
            subStrings.erase(temp);
         }
      }
   }
   return subStrings.size();
}
int main() {
   string str = "01010";
   cout << "The size of the set containing unique strings is " << getSize(str);
   return 0;
}

Output

The size of the set containing unique strings is 8

Time complexity - O(N^4), as O(N^2) is to traverse the set of all substrings, and we used nested loops to traverse the set.

Space complexity - O(N^2) to store all substrings in the set.

Approach 2

In this approach, we will create a list containing 3 parameters: substring length, even 1's, and odd 1's. The reverse of the string will also have the same length, even 1's and odd 1's. If we add unique pairs to the list, we can find all substrings that can follow the list's conditions.

Algorithm

Step 1 - Define the 'setList' set of vector type, as we need to store unique pairs.

Step 2 - Start traversing the string. Also, define the cnt1s, even1s, and odd1s variables and initialize with zero.

Step 3 - Start traversing the substrings. If the character at the qth index is '1', increase cnt1s by 1.

Step 4 - Else, If cnt1s is even, increase even1s. Otherwise, increase odd1s.

Step 5 - Take the length of the substring, and store len, even1s, and odd1s in the set after creating the list.

Step 6 - Return the size of the list.

Example

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

int getSize(string str) {
   // set to store the unique strings
   set<vector<int>> setList;
   // Iterate the string
   for (int p = 0; p < str.length(); p++) {
      // Required variables
      int cnt1s = 0, even1s = 0, odd1s = 0;
      for (int q = p; q < str.length(); q++) {
         // Count the counts of 1's
         if (str[q] == '1') {
            cnt1s++;
         } else {
            // If the count of 1's is even, increment even1s. Otherwise, increment odd1s.
            if (cnt1s % 2 == 0) {
               even1s++;
            } else {
               odd1s++;
            }
         }
         // get substring length
         int len = q - p + 1;
         // Insert the substring in the set
         vector<int> temp;
         temp.push_back(len);
         temp.push_back(even1s);
         temp.push_back(odd1s);
         setList.insert(temp);
      }
   }
   return setList.size();
}
int main() {
   string str = "01010";
   cout << "The size of the set containing unique strings is " << getSize(str);
   return 0;
}

Output

The size of the set containing unique strings is 8

Time complexity - O(N^2), as we create all substrings.

Space complexity - O(N*N) to store the pairs in the set.

The second solution can be a bit harder to understand for beginners, but it's very easy to understand if we say that reverse strings have the same length and parity bits. The first approach's time complexity is much higher. So, it's better to use the second approach to solve the problem.

Updated on: 24-Aug-2023

49 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements