Longest subsequence of the form 0*1*0* in a binary string
Last Updated :
10 Aug, 2022
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 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.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
int longestSubseq(string s)
{
int n = s.length();
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]++;
}
if (pre_count_0[n] == n ||
pre_count_0[n] == 0)
return n;
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;
}
int main()
{
string s = "000011100000" ;
cout << longestSubseq(s);
return 0;
}
|
Java
class GFG
{
public static int longestSubseq(String s)
{
int n = s.length();
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 ]++;
}
if (pre_count_0[n] == n ||
pre_count_0[n] == 0 )
return n;
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;
}
public static void main(String[] args)
{
String s = "000011100000" ;
System.out.println(longestSubseq(s));
}
}
|
Python3
def longestSubseq(s):
n = len (s)
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
if (pre_count_0[n] = = n or
pre_count_0[n] = = 0 ):
return n
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
if __name__ = = '__main__' :
s = "000011100000"
print (longestSubseq(s))
|
C#
using System;
class GFG
{
public static int longestSubseq(String s)
{
int n = s.Length;
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]++;
}
if (pre_count_0[n] == n ||
pre_count_0[n] == 0)
return n;
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;
}
public static void Main(String[] args)
{
String s = "000011100000" ;
Console.WriteLine(longestSubseq(s));
}
}
|
Javascript
<script>
function longestSubseq(s)
{
let n = s.length;
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]++;
}
if (pre_count_0[n] == n ||
pre_count_0[n] == 0)
return n;
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;
}
let s = "000011100000" ;
document.write(longestSubseq(s));
</script>
|
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...