Maximize “10” Subsequences by replacing at most one 0 with 1
Last Updated :
08 Dec, 2022
Given a binary string S consisting of ‘0‘ and ‘1‘ only, the task is to find the maximum possible number of “10” subsequences by replacing at most one 0 with 1.
Examples:
Input: 1110
Output: 3
Explanation: Here initial answer = 3, since pairs: {0, 3}, {1, 3} and {2, 3} initially form the given subsequence. So no need to perform any operations since after performing operation answer would decrease. Hence answer is 3
Input: 101100
Output: 8
Explanation: Here initial answer = 7, since pairs {0, 1}, {0, 4}, {0, 5}, {2, 4}, {2, 5}, {3, 5} and {3, 4} formed the subsequence. If we perform operation on index 1 we get new string as 111100 which gives 8 possible subsequence.
Approach: To solve the problem follow the below idea :
Since it’s allowed to convert a value from ‘0’ to ‘1’, we can think greedily to get our answer.
If we change one ‘0’ to ‘1’, It results in the addition of extra subsequences formed due to changing of ‘0’ to ‘1’. However, it also leads to a loss in a certain amount of subsequences that ‘0’ was initially forming with its previous ‘1’s. Hence we need to select a position such that greedily Net profit = gain(from extra good pairs generated) – loss (originally good pairs destroyed) is maximized.
So how do we calculate it efficiently:
For this purpose, we need to create a suffix array that stores the number of ‘0’ to its right in the string so that we can find the profit after converting that ‘0’ to ‘1’. Also, we need to create a prefix array that stores the number of ‘1’ to its left such that we can find loss after converting that ‘0’ to ‘1’.
Follow the steps to solve the problem:
- Create an array of size N + 1 for storing how many zeros appear after a character.
- Check the last char first, then for the remaining chars by using a loop running from (i = n – 2 to 0).
- Again, do the same thing for storing the appearance of ones in the prefix of any character.
- Calculate the initial answer by adding 0s in the suffix for all indices.
- Run a loop from i = 0 to N:
- Calculate the maximum profit among all the indices.
- Add the initial answer and maximum profit, which is our final answer, and return that value.
Below is the implementation of the approach.
C++
#include <bits/stdc++.h>
using namespace std;
int maximum_subseq(string s)
{
int n = s.length();
vector< int > number_of_zero_suffix(n + 1);
number_of_zero_suffix[n - 1] = (s[n - 1] == '0' );
for ( int i = n - 2; i >= 0; i--) {
number_of_zero_suffix[i]
= number_of_zero_suffix[i + 1] + (s[i] == '0' );
}
vector< int > number_of_one_prefix(n);
number_of_one_prefix[0] = (s[0] == '1' );
for ( int i = 1; i < n; i++) {
number_of_one_prefix[i]
= number_of_one_prefix[i - 1] + (s[i] == '1' );
}
int initial_answer = 0;
for ( int i = 0; i < n; i++) {
if (s[i] == '1' )
initial_answer += number_of_zero_suffix[i + 1];
}
int maxi = 0;
int profit = 0, loss = 0;
for ( int i = 0; i < n; i++) {
if (s[i] == '0' ) {
if (i == n - 1)
profit = 0;
else
profit = number_of_zero_suffix[i + 1];
if (i == 0)
loss = 0;
else
loss = number_of_one_prefix[i - 1];
int net = profit - loss;
maxi = max(maxi, net);
}
}
int answer = initial_answer + maxi;
return answer;
}
int main()
{
string S1 = "1110" ;
cout << maximum_subseq(S1) << "\n" ;
string S2 = "10110" ;
cout << maximum_subseq(S2) << "\n" ;
string S3 = "101100" ;
cout << maximum_subseq(S3) << "\n" ;
return 0;
}
|
Java
import java.io.*;
class GFG {
static int maximum_subseq(String s)
{
int n = s.length();
int [] number_of_zero_suffix = new int [n + 1 ];
number_of_zero_suffix[n - 1 ]
= ((s.charAt(n - 1 ) == '0' ) ? 1 : 0 );
for ( int i = n - 2 ; i >= 0 ; i--) {
number_of_zero_suffix[i]
= number_of_zero_suffix[i + 1 ]
+ ((s.charAt(i) == '0' ) ? 1 : 0 );
}
int [] number_of_one_prefix = new int [n];
number_of_one_prefix[ 0 ]
= (s.charAt( 0 ) == '1' ? 1 : 0 );
for ( int i = 1 ; i < n; i++) {
number_of_one_prefix[i]
= number_of_one_prefix[i - 1 ]
+ ((s.charAt(i) == '1' ? 1 : 0 ));
}
int initial_answer = 0 ;
for ( int i = 0 ; i < n; i++) {
if (s.charAt(i) == '1' ) {
initial_answer
+= number_of_zero_suffix[i + 1 ];
}
}
int maxi = 0 ;
int profit = 0 , loss = 0 ;
for ( int i = 0 ; i < n; i++) {
if (s.charAt(i) == '0' ) {
if (i == n - 1 ) {
profit = 0 ;
}
else {
profit = number_of_zero_suffix[i + 1 ];
}
if (i == 0 ) {
loss = 0 ;
}
else {
loss = number_of_one_prefix[i - 1 ];
}
int net = profit - loss;
maxi = Math.max(maxi, net);
}
}
int answer = initial_answer + maxi;
return answer;
}
public static void main(String[] args)
{
String S1 = "1110" ;
System.out.println(maximum_subseq(S1));
String S2 = "10110" ;
System.out.println(maximum_subseq(S2));
String S3 = "101100" ;
System.out.println(maximum_subseq(S3));
}
}
|
Python3
def maximum_subseq(s):
n = len (s)
number_of_zero_suffix = []
for i in range ( 0 ,n + 1 ):
number_of_zero_suffix.append( 0 )
number_of_zero_suffix[n - 1 ] = (s[n - 1 ] = = '0' )
for i in range (n - 2 , - 1 , - 1 ):
number_of_zero_suffix[i] = number_of_zero_suffix[i + 1 ] + (s[i] = = '0' )
number_of_one_prefix = []
for i in range ( 0 ,n):
number_of_one_prefix.append( 0 )
number_of_one_prefix[ 0 ] = (s[ 0 ] = = '1' )
for i in range ( 1 ,n):
number_of_one_prefix[i] = number_of_one_prefix[i - 1 ] + (s[i] = = '1' )
initial_answer = 0
for i in range ( 0 ,n):
if (s[i] = = '1' ):
initial_answer + = number_of_zero_suffix[i + 1 ]
maxi = 0
profit = 0
loss = 0
for i in range ( 0 ,n):
if (s[i] = = '0' ):
if (i = = n - 1 ):
profit = 0
else :
profit = number_of_zero_suffix[i + 1 ]
if (i = = 0 ):
loss = 0
else :
loss = number_of_one_prefix[i - 1 ]
net = profit - loss
maxi = max (maxi, net)
answer = initial_answer + maxi
return answer
S1 = "1110"
print (maximum_subseq(S1))
S2 = "10110"
print (maximum_subseq(S2))
S3 = "101100"
print (maximum_subseq(S3))
|
C#
using System;
public class GFG {
public static int maximum_subseq( string s)
{
int n = s.Length;
int [] number_of_zero_suffix = new int [n + 1];
if (s[n - 1] == '0' ) {
number_of_zero_suffix[n - 1] = 1;
}
else
number_of_zero_suffix[n - 1] = 0;
for ( int i = n - 2; i >= 0; i--) {
if (s[i] == '0' ) {
number_of_zero_suffix[i]
= number_of_zero_suffix[i + 1] + 1;
}
else {
number_of_zero_suffix[i]
= number_of_zero_suffix[i + 1] + 0;
}
}
int [] number_of_one_prefix = new int [n];
if (s[0] == '1' )
number_of_one_prefix[0] = 1;
else
number_of_one_prefix[0] = 0;
for ( int i = 1; i < n; i++) {
if (s[i] == '1' ) {
number_of_one_prefix[i]
= number_of_one_prefix[i - 1] + 1;
}
else {
number_of_one_prefix[i]
= number_of_one_prefix[i - 1] + 0;
}
}
int initial_answer = 0;
for ( int i = 0; i < n; i++) {
if (s[i] == '1' )
initial_answer
+= number_of_zero_suffix[i + 1];
}
int maxi = 0;
int profit = 0, loss = 0;
for ( int i = 0; i < n; i++) {
if (s[i] == '0' ) {
if (i == n - 1)
profit = 0;
else
profit = number_of_zero_suffix[i + 1];
if (i == 0)
loss = 0;
else
loss = number_of_one_prefix[i - 1];
int net = profit - loss;
maxi = Math.Max(maxi, net);
}
}
int answer = initial_answer + maxi;
return answer;
}
static public void Main()
{
string S1 = "1110" ;
Console.WriteLine(maximum_subseq(S1));
string S2 = "10110" ;
Console.WriteLine(maximum_subseq(S2));
string S3 = "101100" ;
Console.WriteLine(maximum_subseq(S3));
}
}
|
Javascript
function maximum_subseq(s)
{
let n = s.length;
let number_of_zero_suffix = [];
for (let i=0;i<(n + 1);i++)
{
number_of_zero_suffix.push(0);
}
number_of_zero_suffix[n - 1] = (s[n - 1] == '0' );
for (let i = n - 2; i >= 0; i--) {
number_of_zero_suffix[i]
= number_of_zero_suffix[i + 1] + (s[i] == '0' );
}
let number_of_one_prefix = [];
for (let i=0;i<n;i++)
{
number_of_one_prefix.push(0);
};
number_of_one_prefix[0] = (s[0] == '1' );
for (let i = 1; i < n; i++) {
number_of_one_prefix[i]
= number_of_one_prefix[i - 1] + (s[i] == '1' );
}
let initial_answer = 0;
for (let i = 0; i < n; i++) {
if (s[i] == '1' )
initial_answer += number_of_zero_suffix[i + 1];
}
let maxi = 0;
let profit = 0, loss = 0;
for (let i = 0; i < n; i++) {
if (s[i] == '0' ) {
if (i == n - 1)
profit = 0;
else
profit = number_of_zero_suffix[i + 1];
if (i == 0)
loss = 0;
else
loss = number_of_one_prefix[i - 1];
let net = profit - loss;
maxi = Math.max(maxi, net);
}
}
let answer = initial_answer + maxi;
return answer;
}
let S1 = "1110" ;
console.log(maximum_subseq(S1));
let S2 = "10110" ;
console.log(maximum_subseq(S2));
let S3 = "101100" ;
console.log(maximum_subseq(S3));
|
Time complexity: O(N),
Auxiliary Space: O(N)
Related Articles:
Share your thoughts in the comments
Please Login to comment...