Longest subsequence of the form 0*1*0* in a binary string

28 Jun, 2021
Given a binary string, find the longest subsequence of the form (0)*(1)*(0)* in it. Basically we need to divide the string into 3 non overlapping strings (these strings might be empty) without changing the order of letters. First and third strings are made up of only 0 and the second string is made up of only 1. These strings could be made by deleting some characters in original string. What is the maximum size of string, we can get?
Examples: 
Input : 000011100000 
Output : 12
Explanation : 
First part from 1 to 4.
Second part 5 to 7. 
Third part from 8 to 12 

Input : 100001100  
Output : 8
Explanation : 
Delete the first letter. 
First part from 2 to 4. 
Second part from 5 to 6. 
Last part from 7.

Input : 00000 
Output : 5
Explanation : 
Special Case of Only 0

Input : 111111
Output : 6
Explanation : 
Special Case of Only 1

Input : 0000001111011011110000 
Output : 20
Explanation : 
Second part is from 7 to 18. 
Remove all the 0 between indices 7 to 18.
A simple solution is to generate all subsequences of given sequence. For every subsequence, check if it is in given form. If yes, compare it with result so far and update the result if needed.This problem can be efficiently solved by pre-computing below arrays in O(n^2) time.Let pre_count_0[i] be the count of letter 0 in the prefix of string till index i. Let pre_count_1[i] be the count of letter 1 in the prefix of string till length i. Let post_count_0[i] be the count of letter 0 in the suffix string from index i till index n (here n is the size of string).Now we fix two two positions i and j, 1 <=i <= j <=n. We will remove all 0 from substring which starts at index i and ends in index j. Thus this makes the second substring of only 1. In the prefix before the index i and in the postfix after the index j we will delete all 1 and thus it will make first and third part of the string.then the maximum length of string attainable is max of pre_count_0[i-1] + (pre_count_1[j]-pre_count_1[i-1]) + pre_count_1[j+1]Special cases : When String is made of only 0s or 1s, ans is n where n is length of string. 
C++
Java
Python3
C#
Javascript
// CPP program to find longest subsequence// of the form 0*1*0* in a binary string#include <bits/stdc++.h>using namespace std; // Returns length of the longest subsequence// of the form 0*1*0*int longestSubseq(string s){    int n = s.length();     // Precomputing values in three arrays    // pre_count_0[i] is going to store count    //             of 0s in prefix str[0..i-1]    // pre_count_1[i] is going to store count    //             of 1s in prefix str[0..i-1]    // post_count_0[i] is going to store count    //             of 0s in suffix str[i-1..n-1]    int pre_count_0[n + 2];    int pre_count_1[n + 1];    int post_count_0[n + 1];    pre_count_0[0] = 0;    post_count_0[n + 1] = 0;    pre_count_1[0] = 0;    for (int j = 1; j <= n; j++)    {        pre_count_0[j] = pre_count_0[j - 1];        pre_count_1[j] = pre_count_1[j - 1];        post_count_0[n - j + 1] = post_count_0[n - j + 2];         if (s[j - 1] == '0')            pre_count_0[j]++;        else            pre_count_1[j]++;        if (s[n - j] == '0')           post_count_0[n - j + 1]++;    }     // string is made up of all 0s or all 1s    if (pre_count_0[n] == n ||        pre_count_0[n] == 0)        return n;      // Compute result using precomputed values    int ans = 0;    for (int i = 1; i <= n; i++)        for (int j = i; j <= n; j++)            ans = max(pre_count_0[i - 1]                    + pre_count_1[j]                    - pre_count_1[i - 1]                    + post_count_0[j + 1],                    ans);    return ans;} // driver programint main(){    string s = "000011100000";    cout << longestSubseq(s);    return 0;}
// Java program to find longest subsequence// of the form 0*1*0* in a binary stringclass GFG{     // Returns length of the longest subsequence    // of the form 0*1*0*    public static int longestSubseq(String s)    {        int n = s.length();         // Precomputing values in three arrays        // pre_count_0[i] is going to store count        // of 0s in prefix str[0..i-1]        // pre_count_1[i] is going to store count        // of 1s in prefix str[0..i-1]        // post_count_0[i] is going to store count        // of 0s in suffix str[i-1..n-1]        int[] pre_count_0 = new int[n + 2];        int[] pre_count_1 = new int[n + 1];        int[] post_count_0 = new int[n + 2];        pre_count_0[0] = 0;        post_count_0[n + 1] = 0;        pre_count_1[0] = 0;        for (int j = 1; j <= n; j++)        {            pre_count_0[j] = pre_count_0[j - 1];            pre_count_1[j] = pre_count_1[j - 1];            post_count_0[n - j + 1] = post_count_0[n - j + 2];             if (s.charAt(j - 1) == '0')                pre_count_0[j]++;            else                pre_count_1[j]++;             if (s.charAt(n - j) == '0')                post_count_0[n - j + 1]++;        }         // string is made up of all 0s or all 1s        if (pre_count_0[n] == n ||            pre_count_0[n] == 0)            return n;         // Compute result using precomputed values        int ans = 0;        for (int i = 1; i <= n; i++)            for (int j = i; j <= n; j++)                ans = Math.max(pre_count_0[i - 1] +                               pre_count_1[j] -                               pre_count_1[i - 1] +                               post_count_0[j + 1], ans);        return ans;    }     // Driver code    public static void main(String[] args)    {        String s = "000011100000";        System.out.println(longestSubseq(s));    }} // This code is contributed by// sanjeev2552
# Python 3 program to find longest subsequence# of the form 0*1*0* in a binary string # Returns length of the longest subsequence# of the form 0*1*0*def longestSubseq(s):    n = len(s)     # Precomputing values in three arrays    # pre_count_0[i] is going to store count    #         of 0s in prefix str[0..i-1]    # pre_count_1[i] is going to store count    #         of 1s in prefix str[0..i-1]    # post_count_0[i] is going to store count    #         of 0s in suffix str[i-1..n-1]    pre_count_0 = [0 for i in range(n + 2)]    pre_count_1 = [0 for i in range(n + 1)]    post_count_0 = [0 for i in range(n + 2)]    pre_count_0[0] = 0    post_count_0[n + 1] = 0    pre_count_1[0] = 0    for j in range(1, n + 1):        pre_count_0[j] = pre_count_0[j - 1]        pre_count_1[j] = pre_count_1[j - 1]        post_count_0[n - j + 1] = post_count_0[n - j + 2]         if (s[j - 1] == '0'):            pre_count_0[j] += 1        else:            pre_count_1[j] += 1        if (s[n - j] == '0'):            post_count_0[n - j + 1] += 1     # string is made up of all 0s or all 1s    if (pre_count_0[n] == n or        pre_count_0[n] == 0):        return n     # Compute result using precomputed values    ans = 0    for i in range(1, n + 1):        for j in range(i, n + 1, 1):            ans = max(pre_count_0[i - 1] +                      pre_count_1[j] -                      pre_count_1[i - 1] +                      post_count_0[j + 1], ans)    return ans # Driver Codeif __name__ == '__main__':    s = "000011100000"    print(longestSubseq(s))     # This code is contributed by# Surendra_Gangwar
// C# program to find longest subsequence// of the form 0*1*0* in a binary stringusing System;     class GFG{     // Returns length of the longest subsequence    // of the form 0*1*0*    public static int longestSubseq(String s)    {        int n = s.Length;         // Precomputing values in three arrays        // pre_count_0[i] is going to store count        // of 0s in prefix str[0..i-1]        // pre_count_1[i] is going to store count        // of 1s in prefix str[0..i-1]        // post_count_0[i] is going to store count        // of 0s in suffix str[i-1..n-1]        int[] pre_count_0 = new int[n + 2];        int[] pre_count_1 = new int[n + 1];        int[] post_count_0 = new int[n + 2];        pre_count_0[0] = 0;        post_count_0[n + 1] = 0;        pre_count_1[0] = 0;        for (int j = 1; j <= n; j++)        {            pre_count_0[j] = pre_count_0[j - 1];            pre_count_1[j] = pre_count_1[j - 1];            post_count_0[n - j + 1] = post_count_0[n - j + 2];             if (s[j - 1] == '0')                pre_count_0[j]++;            else                pre_count_1[j]++;             if (s[n - j] == '0')                post_count_0[n - j + 1]++;        }         // string is made up of all 0s or all 1s        if (pre_count_0[n] == n ||            pre_count_0[n] == 0)            return n;         // Compute result using precomputed values        int ans = 0;        for (int i = 1; i <= n; i++)            for (int j = i; j <= n; j++)                ans = Math.Max(pre_count_0[i - 1] +                               pre_count_1[j] -                               pre_count_1[i - 1] +                               post_count_0[j + 1], ans);        return ans;    }     // Driver code    public static void Main(String[] args)    {        String s = "000011100000";        Console.WriteLine(longestSubseq(s));    }} // This code is contributed by Princi Singh
<script> // Javascript program to find longest subsequence// of the form 0*1*0* in a binary string // Returns length of the longest subsequence// of the form 0*1*0*function longestSubseq(s){    let n = s.length;     // Precomputing values in three arrays    // pre_count_0[i] is going to store count    // of 0s in prefix str[0..i-1]    // pre_count_1[i] is going to store count    // of 1s in prefix str[0..i-1]    // post_count_0[i] is going to store count    // of 0s in suffix str[i-1..n-1]    let pre_count_0 = new Array(n + 2);    let pre_count_1 = new Array(n + 1);    let post_count_0 = new Array(n + 2);    pre_count_0[0] = 0;    post_count_0[n + 1] = 0;    pre_count_1[0] = 0;         for(let j = 1; j <= n; j++)    {        pre_count_0[j] = pre_count_0[j - 1];        pre_count_1[j] = pre_count_1[j - 1];        post_count_0[n - j + 1] = post_count_0[n - j + 2];         if (s[j - 1] == '0')            pre_count_0[j]++;        else            pre_count_1[j]++;         if (s[n - j] == '0')            post_count_0[n - j + 1]++;    }     // String is made up of all 0s or all 1s    if (pre_count_0[n] == n ||        pre_count_0[n] == 0)        return n;     // Compute result using precomputed values    let ans = 0;    for(let i = 1; i <= n; i++)        for(let j = i; j <= n; j++)            ans = Math.max(pre_count_0[i - 1] +                           pre_count_1[j] -                           pre_count_1[i - 1] +                           post_count_0[j + 1], ans);    return ans;} // Driver codelet s = "000011100000"; document.write(longestSubseq(s)); // This code is contributed by vaibhavrabadiya3 </script>
Output : 
12
This article is contributed by nikhil ranjan 7. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above. 
SURENDRA_GANGWAR
sanjeev2552
princi singh
vaibhavrabadiya3
binary-string
prefix-sum
subsequence
Strings
prefix-sum
Strings
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Top 50 String Coding Problems for Interviews
What is Data Structure: Types, Classifications and Applications
Print all the duplicates in the input string
Print all subsequences of a string
A Program to check if strings are rotations of each other or not
String class in Java | Set 1
Find if a string is interleaved of two other strings | DP-33
Check if an URL is valid or not using Regular Expression
Remove first and last character of a string in Java
Find the smallest window in a string containing all characters of another string