Count of triplets in Binary String such that Bitwise AND of S[i], S[j] and S[j], S[k] are same


A binary string is a type of string which contains only binary characters that are '0' and '1'. We are given a binary string and have to find the triplets that fulfill the condition that the bitwise 'AND' of the first two characters is equal to the bitwise 'AND' of the last two characters.

Mathematically:

For 0 <= i < j < k < length (given string): (s[i] & s[j]) == (s[j] & s[k])

Bitwise 'AND' is true if both the bits are true otherwise for anyone false or both false it returns false.

Sample Example

Input

“01010”

Output

8

Explanation

For the 0 present at the 0th index we can have triplets (0, 1, 0), (0, 1, 0) (0, 0, 1), (0, 1, 0), and (0, 0, 0).

For the next 1: (1, 0, 1), and (1, 0, 0)

For the next 0: (0, 1, 0)

Approach 1

In this program, we are going to use the brute force approach to get all the triplets and then we will check for each of them whether they follow the given condition or not.

  • First, we will create a function, that will take a single parameter that is given string and it will return the required result.

  • In the function, we will get the size of the string and then use the nested for loop to traverse over the string and get all the triplets.

  • We will maintain a variable to store the count and if any triplet met the given condition then we will increase the count.

  • In the main function, we will call the function and print the result.

Example

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

// function to get the required solution 
int countTriplets(string str){
   int len = str.size(); // getting the size of string 
   int ans = 0; // variable to store the count 
   // use nested three for loops to get all the triplets 
   for (int i = 0; i < len; i++){
      int a = str[i] -'0'; // current bit 
      for (int j = i + 1; j < len; j++){
         int b = str[j] - '0'; // current bit
         for (int k = j + 1; k < len; k++){
            int c = str[k] - '0'; // current bit
            
            if((a & b) == (b & c)){
               ans++; // increasing the count 
            }
         }
      }
   }
   return ans; // return the final count
}
int main(){
   string str = "01010"; // given string 
   cout<<"The number of triplets in the given string is: " << countTriplets(str) << endl;
   return 0;
}

Output

The number of triplets in the given string is: 8

Time and Space Complexity

The time complexity of the above code is O(N^3) where N is the size of the given string. Here we are traversing over the string in nested for loops three times making the time complexity high.

We are not using any extra space here, which makes the space complexity of the above code O(1) or constant.

Approach 2

In this approach, we are going to use the prefix and suffix array to store the count of the zeros to reduce the time complexity.

We will maintain the arrays and will traverse over the given string to get the result.

In the traversal, if the current index of the string is '0' then we will simply add the current index number multiplied by the remaining index's minus one.

If the current index value is '1' then we will use the concept of the prefix * suffix and index minus prefix multiplied by the remaining elements minus the suffix and this will give us the final answer.

Example

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

// function to ge the required solution 
int countTriplets(string str){
   int len = str.size(); // getting size of string 
   int ans = 0; // variable to store the count 
   int prefix[len], suffix[len];
   // traversing over the string to get the prefix array 
   prefix[0] = str[0] == '0';
   for (int i = 1; i < len; ++i) {
      prefix[i] = prefix[i-1] + (str[i] == '0');
   }
   // traversing over the string to get the suffix array 
   suffix[len-1] = str[len-1] == '0';
   for (int i = len - 2; i >= 0; --i) {
      suffix[i] = suffix[i+1] + (str[i] == '0');
   }
   // iterating over the string to get the final answer 
   for (int i = 1; i < len - 1; i++) {
      if (str[i] == '0') {
         ans += i * (len - i - 1);
      }
      else {
         ans += prefix[i - 1] * suffix[i + 1];
         ans += (i - prefix[i - 1]) * (len - i - 1 - suffix[i + 1]);
      }
   }
   return ans; // return the final count
}
int main(){
   string str = "01010"; // given string 
   cout<<"The number of triplets in the given string is: "<<countTriplets(str)<<endl;
   return 0;
}

Output

The number of triplets in the given string is: 8

Time and Space Complexity

The time complexity of the above code is O(N) where N is the size of the given string.

In the above code, we are using the extra arrays to store the prefix and suffix count of the zeroes making the space complexity linear that is O(N).

Conclusion

In this tutorial, we have implemented a program to find the number of triplets present in the given binary string that follows the given condition: For 0 <= i < j < k < length (given string): (s[i] & s[j]) == (s[j] & s[k]). We have implemented two programs, one is with the nested for loops and finding all the triplets with brute force and another is by maintaining the prefix and suffix sum and mathematically finding the result.

Updated on: 31-Aug-2023

46 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements