- Data Structure
- Networking
- RDBMS
- Operating System
- Java
- MS Excel
- iOS
- HTML
- CSS
- Android
- Python
- C Programming
- C++
- C#
- MongoDB
- MySQL
- Javascript
- PHP
- Physics
- Chemistry
- Biology
- Mathematics
- English
- Economics
- Psychology
- Social Studies
- Fashion Studies
- Legal Studies
- 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 ways to select three indices from Binary String with different adjacent digits
In this problem, we will find the number of pairs of 3 indices so that any adjacent indices don’t have the same value in the pair.
We can get the output by checking each pair of 3 indexes, but it can be more time-consuming. Another approach to solving the problem is to take the current index and also take the index from left and right, which doesn’t contain a similar value to the current index's value. This way, we can count the total number of pairs each index can form and sum them to get the output.
Problem statement − We have given a bin_str binary string and need to find the number of pairs of 3 indexes in increasing order, such that adjacent indices don’t contain the same value.
Sample Examples
Input
bin_str = "0101";
Output
2
Explanation
We can take the {0, 1, 2} and {1, 2, 3} index pairs. So, in the 010 and 101 strings, any two adjacent characters are not the same.
Input
bin_str = "110001";
Output
6
Explanation
We can take {0, 2, 5}, {0, 3, 5}, {0, 4, 5}, {1, 2, 5}, {1, 3, 5}, and {1, 4, 5}.
Input
bin_str = “11111”
Output
0
Explanation
As all characters of the string are same, it doesn’t contain any required pairs of indices.
Approach 1
In this approach, we will use three nested loops to find the pair of 3 indices so that the adjacent index doesn’t contain the same value. We will check for each pair whether it follows the conditions given in the problem statement.
Algorithm
Step 1 − Initialize the ‘ans’ with 0 to store the number of required pairs.
Step 2 − Use the first loop to traverse the string from the 0th index to the binary string’s length – 3 index.
Step 3 − Use a nested loop to traverse from the (p + 1) index to the binary string’s length – 2 index.
Step 4 − Use another nested loop to traverse the string from the (q + 1) index to the binary string’s length – 1.
Step 5 − In the nested loop, if the character at the p and q index are not same, and the character at the q and r index is not same, increment the ‘ans’ value by 1.
Step 6 − Return the value of ‘ans’.
Example
Following are the examples to the above algorithm −
#include <stdio.h> #include <string.h> long long findIndexSelection(char* bin_str) { int bin_len = strlen(bin_str); long long ans = 0; // Creating the pair of 3 indexes for (int p = 0; p < bin_len - 2; p++) { for (int q = p + 1; q < bin_len - 1; q++) { for (int r = q + 1; r < bin_len; r++) { // Check whether adjacent characters are not the same if (bin_str[p] != bin_str[q] && bin_str[q] != bin_str[r]) { ans++; } } } } // Final output return ans; } int main() { char bin_str[] = "0101"; printf("The maximum number of ways to select indexes such that two adjacent indexes don't have the same character is %lld\n", findIndexSelection(bin_str)); return 0; }
Output
The maximum number of ways to select indexes such that two adjacent indexes don't have the same character is 2
#include <bits/stdc++.h> using namespace std; long long findIndexSelection(string bin_str) { int bin_len = bin_str.size(); int ans = 0; // Creating the pair of 3 indexes for (int p = 0; p < bin_len - 2; p++) { for (int q = p + 1; q < bin_len - 1; q++) { for (int r = q + 1; r < bin_len; r++) { // Check whether adjacent characters are the same or not if (bin_str[p] != bin_str[q] && bin_str[q] != bin_str[r]) { ans++; } } } } // Final output return ans; } int main() { string bin_str = "0101"; cout << "The maximum number of ways to select indexes such that two adjacent indexes don't have the same character is " << findIndexSelection(bin_str) << endl; return 0; }
Output
The maximum number of ways to select indexes such that two adjacent indexes don't have the same character is 2
public class Main { public static long findIndexSelection(String binStr) { int binLen = binStr.length(); long ans = 0; // Creating the pair of 3 indexes for (int p = 0; p < binLen - 2; p++) { for (int q = p + 1; q < binLen - 1; q++) { for (int r = q + 1; r < binLen; r++) { // Check whether adjacent characters are not the same if (binStr.charAt(p) != binStr.charAt(q) && binStr.charAt(q) != binStr.charAt(r)) { ans++; } } } } // Final output return ans; } public static void main(String[] args) { String binStr = "0101"; System.out.println("The maximum number of ways to select indexes such that two adjacent indexes don't have the same character is " + findIndexSelection(binStr)); } }
Output
The maximum number of ways to select indexes such that two adjacent indexes don't have the same character is 2
def find_index_selection(bin_str): bin_len = len(bin_str) ans = 0 # Creating the pair of 3 indexes for p in range(bin_len - 2): for q in range(p + 1, bin_len - 1): for r in range(q + 1, bin_len): # Check whether adjacent characters are not the same if bin_str[p] != bin_str[q] and bin_str[q] != bin_str[r]: ans += 1 return ans if __name__ == "__main__": bin_str = "0101" print("The maximum number of ways to select indexes such that two adjacent indexes don't have the same character is", find_index_selection(bin_str))
Output
The maximum number of ways to select indexes such that two adjacent indexes don't have the same character is 2
Time complexity − O(N*N*N), as we use three nested loops.
Space complexity − O(1) as we don’t use any dynamic space.
Approach 2
If we want to make a pair using the current index, we need to take one left index and one right index, as we need to choose indexes in increasing order. So, we can take all indexes from the left and right that don’t contain the same character as the current index.
The number of pairs we can construct using the current index is given below.
Pairs = (number of left indexes have dissimilar value) * (number of right indexes have dissimilar value)
After that, we can sum the pairs we can construct using each index.
Algorithm
Step 1 − Initialize the ‘cnt1’ and ‘cnt0’ variables to store the count of zeros and ones in the given binary string.
Step 2 − Traverse the string and update the count of zeros and ones.
Step 3 − Initialize the ‘ans’ with 0 to store total pairs.
Step 4 − Traverse the string to find total valid pairs.
Step 5 − If the current character is ‘0’, add (ones* (cnt1 - ones)) to the ‘ans’. We take multiplication left and right 1’s, which forms the pair like 101. Also, increment ‘zeros’ by 1.
Step 6 − If the current character is ‘1’, add (zeros * (cnt0 – zeros)) to the ‘ans’. It forms a string like 010. Next, increment ‘ones’ by 1.
Step 7 − Return the ‘ans’ value.
Example
Following are the examples to the above algorithm −
#include <stdio.h> #include <string.h> long long findIndexSelection(char* bin_str) { int bin_len = strlen(bin_str); // Counting the number of zeros and ones int cnt0 = 0, cnt1 = 0; // To store zeros and ones till ith index int zeros = 0, ones = 0; // Traverse the string to count 0's and 1's for (int p = 0; p < bin_len; p++) { if (bin_str[p] == '0') { cnt0++; } else { cnt1++; } } // To store the maximum number of pairs long long ans = 0; // Finding pairs for (int p = 0; p < bin_len; p++) { if (bin_str[p] == '0') { // Getting the number of pairs that can be formed with the current index ans += (ones * (cnt1 - ones)); // Increase zeros zeros++; } else { // Getting the number of pairs that can be formed with the current index ans += (zeros * (cnt0 - zeros)); ones++; } } return ans; } int main() { char bin_str[] = "1010"; printf("The maximum number of ways to select indexes such that two adjacent indexes don't have the same character is %lld\n", findIndexSelection(bin_str)); return 0; }
Output
The maximum number of ways to select indexes such that two adjacent indexes don't have the same character is 2
#include <bits/stdc++.h> using namespace std; long long findIndexSelection(string bin_str) { int bin_len = bin_str.size(); // Counting the number of zeros and ones int cnt0 = 0, cnt1 = 0; // To store zeros and ones till ith index int zeros = 0, ones = 0; // Traverse the string to count 0's and 1's for (int p = 0; p < bin_len; p++) { if (bin_str[p] == '0') { cnt0++; } else { cnt1++; } } // To store the maximum number of pairs long long ans = 0; // Finding pairs for (int p = 0; p < bin_len; p++) { if (bin_str[p] == '0') { // Getting the number of pairs can be formed with a current index ans += (ones * (cnt1 - ones)); // Increase zeros zeros++; } else { // Getting the number of pairs can be formed with a current index ans += (zeros * (cnt0 - zeros)); ones++; } } return ans; } int main() { string bin_str = "1010"; cout << "The maximum number of ways to select indexes such that two adjacent indexes don't have the same character is " << findIndexSelection(bin_str) << endl; return 0; }
Output
The maximum number of ways to select indexes such that two adjacent indexes don't have the same character is 2
public class Main { public static long findIndexSelection(String binStr) { int binLen = binStr.length(); // Counting the number of zeros and ones int cnt0 = 0, cnt1 = 0; // To store zeros and ones till ith index int zeros = 0, ones = 0; // Traverse the string to count 0's and 1's for (int p = 0; p < binLen; p++) { if (binStr.charAt(p) == '0') { cnt0++; } else { cnt1++; } } // To store the maximum number of pairs long ans = 0; // Finding pairs for (int p = 0; p < binLen; p++) { if (binStr.charAt(p) == '0') { // Getting the number of pairs that can be formed with the current index ans += (ones * (cnt1 - ones)); // Increase zeros zeros++; } else { // Getting the number of pairs that can be formed with the current index ans += (zeros * (cnt0 - zeros)); ones++; } } return ans; } public static void main(String[] args) { String binStr = "1010"; System.out.println("The maximum number of ways to select indexes such that two adjacent indexes don't have the same character is " + findIndexSelection(binStr)); } }
Output
The maximum number of ways to select indexes such that two adjacent indexes don't have the same character is 2
def find_index_selection(bin_str): bin_len = len(bin_str) # Counting the number of zeros and ones cnt0 = 0 cnt1 = 0 # To store zeros and ones till ith index zeros = 0 ones = 0 # Traverse the string to count 0's and 1's for p in range(bin_len): if bin_str[p] == '0': cnt0 += 1 else: cnt1 += 1 # To store the maximum number of pairs ans = 0 # Finding pairs for p in range(bin_len): if bin_str[p] == '0': # Getting the number of pairs that can be formed with the current index ans += (ones * (cnt1 - ones)) # Increase zeros zeros += 1 else: # Getting the number of pairs that can be formed with the current index ans += (zeros * (cnt0 - zeros)) ones += 1 return ans if __name__ == "__main__": bin_str = "1010" print("The maximum number of ways to select indexes such that two adjacent indexes don't have the same character is", find_index_selection(bin_str))
Output
The maximum number of ways to select indexes such that two adjacent indexes don't have the same character is 2
Time complexity – O(N) to traverse the string.
Space complexity – O(1), as we don’t use any dynamic space.
We learned the naïve approach and optimized approach to solve the problem. The first approach has high time complexity and can’t be used for large inputs. The second approach uses the concept of prefixes 1s and 0s to solve the problem.