Generate Binary String with equal number of 01 and 10 Subsequence


In this problem, we will find the binary string of the given length having the same number of ‘01’ and ‘10’ subsequences.

The naïve approach to solving the problem is to generate all binary strings of the given length and check whether it contains the same number of ‘10’ and ‘01’ subsequences using the dynamic programming technique.

Another efficient approach is to prepare a binary string based on whether the given length is odd or even.

Problem statement − We have given a positive integer ‘len’ which is greater than 2. The task is to find the binary string of the ‘len’ length containing the equal number of ‘10’ and ‘01’ subsequences. Also, the string should contain at least one ‘1’ and ‘0’.

Sample examples

Input

len = 4;

Output

1001

Explanation − The 1001 string contains the two 10 and 01 subsequences. The other answer can be 0110.

Input

len = 5;

Output

11011

Explanation − The 11011 substring contains the two 10 and 01 subsequences. We can also print the 00100 string in the answer.

Input

len = 3;

Output

010

Explanation − The answer can be 010 and 101.

Approach 1

In this approach, we will use the recursive function to generate all binary strings of the given length. Also, we will use tabular dynamic programming to check whether the generated string contains an equal number of 10 and 01 subsequences.

Algorithm

Step 1 − In the binStrUtil() function, if the temp string’s length is equal to the ‘len’, execute the totalSubSeqs() function to count a number of ‘10’ and ‘01’ subsequences in the given string.

Step 2.1 − In the totalSubSeqs() function, initialize the ‘cnt’ with 0 and ‘matrix’ of dimensions str_len + 1 x subseq_len + 1 with 0.

Step 2.2 −Traverse the matrix using two nested loops.

Step 2.3 − If q is 0, update the matrix[p][q] with 1, as an empty subsequence always exists.

Step 2.4 − If p is 0, update the matrix[p][q] with 0; no subsequence exists for strings with length 0.

Step 2.3 − In other cases, If characters at p−1 and q − 1 index are the same, update the matrix[p][q] with matrix[p − 1][q− 1] + matrix[p − 1][q], where matrix[p − 1][q − 1], counts the subsequences by considering the current character and matrix[p−1][q] counts the subsequences without considering the current character.

Step 2.4 − Otherwise, update the matrix[p][q] with the matrix[p−1][q], as we don’t need to consider the current character if they are not same.

Step 2.5 − Return the matrix[strLen][sub_len] value from the function.

Step 3 −If ‘10’ and ‘01’ subsequences are the same in the string, and at least one ‘1’ and ‘0’ exists, update the ‘answer’ with the ‘temp’ string.

Step 4 − Next, append ‘0’ to the temp, and make a recursive call using the binaryUtil() function. Also, remove the last character from the string.

Step 5 − Append ‘1’ to the ‘temp’ string and make a recursive call. Also, remove the last character from the string.

Example

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

string answer = "";
int totalSubSeqs(const string &temp, const string &sub) {
    int cnt = 0;
    int sub_len = sub.length();
    int strLen = temp.length();
    int matrix[strLen + 1][sub_len + 1] = {0};
    // Fill the matrix
    for (int p = 0; p <= strLen; p++) {
        for (int q = 0; q <= sub_len; q++) {
            // Base cases
            if (q == 0) {
                matrix[p][q] = 1;
            } else if (p == 0) {
                // For strings with length 0.
                matrix[p][q] = 0;
            } else {
                // When characters are the same
                if (temp[p - 1] == sub[q - 1]) {
                    matrix[p][q] = matrix[p - 1][q - 1] + matrix[p - 1][q];
                } else {
                    matrix[p][q] = matrix[p - 1][q];
                }
            }
        }
    }
    cnt = matrix[strLen][sub_len];
    return cnt;
}
void binStrUtil(string &temp, int len) {
    if (temp.length() == len) {
        // New binary string found
        // If cnt of 10 and 01 subsequences are the same, choose it as the answer
        if (totalSubSeqs(temp, "10") == totalSubSeqs(temp, "01")) {
            if (count(temp.begin(), temp.end(), '1') > 0 && count(temp.begin(), temp.end(), '0') > 0)
                answer = temp;
        }
        return;
    }
    // Insert 0 and backtrack
    temp += '0';
    binStrUtil(temp, len);
    temp.pop_back();
    // Insert 1 at the current index and backtrack
    temp += '1';
    binStrUtil(temp, len);
    temp.pop_back();
}
int main() {
    int len = 4;
    string temp;
    binStrUtil(temp, len);
    cout << "The binary string of the given length and following the given condition is: " << answer << endl;
    return 0;
}

Output

The binary string of the given length and following the given condition is: 1001

Time complexity − O(N*2N), where O(N) is for finding the total number of 10 and 01 subsequences in the string, and O(2N) is for finding all binary strings.

Space complexity − O(N) for matrix[] array and store the binary string.

Approach 2

For the even length of a binary string, if we place the ‘1’ at len/2 and len/2 − 1 index and place ‘0’ at other indexes, we can get the binary string having equal 01 and 10 subsequences.

For the odd length of a binary string, if we place ‘1’ at the len/2 index and place ‘0’at other indexes, we can get the required binary string of the given length.

Algorithm

Step 1 − Initialize the ‘temp’ string and ‘middle’ with the ‘len/2’.

Step 2 − If the length is even, follow the below steps.

Step 2.1 − Make iterations equal to the given ‘len’. If current index is equal to the middle or middle – 1, append ‘1’ to the temp string. Otherwise, append ‘0’ to the ‘temp’ string.

Step 3 − If the given length is odd, follow the below steps.

Step 3.1 − Make iterations equal to the given ‘len’. If the current index is equal to the middle, append ‘1’ to the ‘temp’ string. Otherwise, append ‘0’ to the ‘temp’ string.

Step 4 − Return the ‘temp’ string.

Example

#include <iostream>
using namespace std;

string getBinStr(int len) {
    string temp = "";
    // Get middle of the length
    int middle = len / 2;
    // For even length
    if (len % 2 == 0) {
        for (int p = 0; p < len; p++) {
            // Place two 1's at the middle
            if (p == middle || p == middle - 1) {
                temp += "1";
            } else {
                // Place 0's at the remaining places
                temp += "0";
            }
        }
        // Return the final binary string
        return temp;
    }
    // For odd length
    else {
        for (int p = 0; p < len; p++) {
            // Insert '1' at middle index
            if (p == middle) {
                temp += "1";
            } else {
                // Insert '0' at other indexes
                temp += "0";
            }
        }
        // Return the final binary string
        return temp;
    }
}
int main() {
    int len = 5;
    cout << "The binary string of the given length and following the given condition is " << getBinStr(len) << endl;
    return 0;
}

Output

The binary string of the given length and following the given condition is 00100

Time complexity − O(len) to generate a binary string of the given length.

Space complexity − O(len) to store the binary string.

The second approach is based on observation, which is far more efficient than the first. In the second approach, we can also print ‘0’ at middle indexes and ‘1’ at other indexes.

Updated on: 17-Jul-2023

181 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements