Open In App

Longest Subsequence with equal 0s and 1s and all 0s before all 1s

Last Updated : 14 Jul, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given a binary string S, the task is to find the longest subsequence with that has equal number of 0s and 1s and all the 0s are present before all the 1s.

Examples:

Input: S = “0011001111”
Output: 8
Explanation: By removing the 3rd and 4th characters, the string becomes 00001111. 
This is the longest possible subsequence following the given conditions.

Input: S = “11001”
Output: 2
Explanation: The longest possible subsequence satisfying the conditions is “01”

Input: S = “111100”
Output: 0
Explanation: There is no such subsequence that satisfies the conditions.

 

 Approach: The problem can be solved based on the following idea:

For each index, we need to pick the maximum number of 0s from the starting and the maximum number of 1s from the rear end. This will maximize the length of the required subsequence.

Based on the above idea, we need to do the following: 

  • For each index, calculate the total number of 0s from the start and the total number of 1s from the end. 
  • If the 1s begin from ith index then the total length of the subsequence will be = 2 * min(0s from start till i, 1s from end till i)
  • The maximum of this for all indices is the answer.

Follow the steps mentioned below to implement the idea:

  • Build two arrays (say pre[] and post[]) to store the count of 0s from the start and the count of 1s from the end.
  • Iterate from i = 0 to N-1:
    • If S[i] is 0, increment the count of 0s and store it in pre[i].
  • Iterate from i = N-1 to 0:
    • If S[i] is 1, increment the count 1s from end and store it in post[i].
  • Iterate the arrays from i = 0 to N-1:
    • Calculate the length of the subsequence if this index is the breaking point between 1s and 0s.
    • Maximum among these subsequences is the required length of the subsequence.

Below is the implementation of the above approach.

C++




// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the length
// of the longest subsequence
int longestGoodString(string s)
{
    // Size of the string
    int n = s.size();
 
    // The pre is used to store the count of 0s
    // encountered from start to i index
 
    // The post is used to store the count of 1s
    // encountered from n-1 index to i index
    vector<int> pre(n, 0), post(n, 0);
 
    if (s[0] == '0')
        pre[0] = 1;
 
    // Loop to calculate the value of pre[i]
    for (int i = 1; i < n; i++) {
        if (s[i] == '0')
            pre[i] = pre[i - 1] + 1;
        else
            pre[i] = pre[i - 1];
    }
 
    if (s[n - 1] == '1')
        post[n - 1] = 1;
 
    // Loop to calculate the value of post[i]
    for (int i = n - 2; i >= 0; i--) {
        if (s[i] == '1')
            post[i] = 1 + post[i + 1];
        else
            post[i] = post[i + 1];
    }
 
    // Picking up the maximum possible length
    int ans = 0;
    for (int i = 0; i < n; i++) {
        ans = max(ans, 2 * min(pre[i], post[i]));
    }
 
    // Return the maximum length as answer
    return ans;
}
 
// Driver code
int main()
{
    string S = "0011001111";
 
    // Function call
    cout << longestGoodString(S);
    return 0;
}


Java




// Java code to implement the approach
import java.io.*;
 
class GFG
{
 
  // Function to find the length
  // of the longest subsequence
  public static int longestGoodString(String s)
  {
    // Size of the string
    int n = s.length();
 
    // The pre is used to store the count of 0s
    // encountered from start to i index
 
    // The post is used to store the count of 1s
    // encountered from n-1 index to i index
    int pre[] = new int[n];
    int post[] = new int[n];
 
    if (s.charAt(0) == '0')
      pre[0] = 1;
 
    // Loop to calculate the value of pre[i]
    for (int i = 1; i < n; i++) {
      if (s.charAt(i) == '0')
        pre[i] = pre[i - 1] + 1;
      else
        pre[i] = pre[i - 1];
    }
 
    if (s.charAt(n - 1) == '1')
      post[n - 1] = 1;
 
    // Loop to calculate the value of post[i]
    for (int i = n - 2; i >= 0; i--) {
      if (s.charAt(i) == '1')
        post[i] = 1 + post[i + 1];
      else
        post[i] = post[i + 1];
    }
 
    // Picking up the maximum possible length
    int ans = 0;
    for (int i = 0; i < n; i++) {
      ans = Math.max(ans,
                     2 * Math.min(pre[i], post[i]));
    }
 
    // Return the maximum length as answer
    return ans;
  }
 
  // Driver Code
  public static void main(String[] args)
  {
    String S = "0011001111";
 
    // Function call
    System.out.print(longestGoodString(S));
  }
}
 
// This code is contributed by Rohit Pradhan


Python3




# Python3 code to implement the approach
# Function to find the length
# of the longest subsequence
def longestGoodString(s):
    # Size of the string
    n =  len(s)
 
    # The pre is used to store the count of 0s
    # encountered from start to i index
 
    # The post is used to store the count of 1s
    # encountered from n-1 index to i index
    pre = []
    post=[]
       
    for i in range(n):
      pre.append(0)
      post.append(0)
 
    if (s[0] is '0'):
        pre[0] = 1
 
    # Loop to calculate the value of pre[i]
    for i in range(1,n):
        if (s[i] is '0'):
            pre[i] = pre[i - 1] + 1
        else:
            pre[i] = pre[i - 1]
 
    if (s[n - 1] is '1'):
        post[n - 1] = 1
 
    # Loop to calculate the value of post[i]
    for i in range(n-2,-1,-1):
        if (s[i] is '1'):
            post[i] = 1 + post[i + 1]
        else:
            post[i] = post[i + 1]
 
    # Picking up the maximum possible length
    ans = 0
    for i in range(n):
        ans = max(ans, 2 * min(pre[i], post[i]))
 
    # Return the maximum length as answer
    return ans
 
# Driver code
S = "0011001111"
 
# Function call
print(longestGoodString(S))
 
# This code is contributed by akashish__


C#




// C# code to implement the approach
using System;
public class GFG
{
 
  // Function to find the length
  // of the longest subsequence
  public static int longestGoodString(String s)
  {
    // Size of the string
    int n = s.Length;
 
    // The pre is used to store the count of 0s
    // encountered from start to i index
 
    // The post is used to store the count of 1s
    // encountered from n-1 index to i index
    int []pre = new int[n];
    int []post = new int[n];
 
    if (s[0] == '0')
      pre[0] = 1;
 
    // Loop to calculate the value of pre[i]
    for (int i = 1; i < n; i++) {
      if (s[i] == '0')
        pre[i] = pre[i - 1] + 1;
      else
        pre[i] = pre[i - 1];
    }
 
    if (s[n - 1] == '1')
      post[n - 1] = 1;
 
    // Loop to calculate the value of post[i]
    for (int i = n - 2; i >= 0; i--) {
      if (s[i] == '1')
        post[i] = 1 + post[i + 1];
      else
        post[i] = post[i + 1];
    }
 
    // Picking up the maximum possible length
    int ans = 0;
    for (int i = 0; i < n; i++) {
      ans = Math.Max(ans,
                     2 * Math.Min(pre[i], post[i]));
    }
 
    // Return the maximum length as answer
    return ans;
  }
 
  // Driver Code
  public static void Main(string[] args)
  {
    string S = "0011001111";
 
    // Function call
    Console.WriteLine(longestGoodString(S));
  }
}
 
// This code is contributed by AnkThon


Javascript




<script>
        // JavaScript code to implement the approach
 
        // Function to find the length
        // of the longest subsequence
        const longestGoodString = (s) => {
            // Size of the string
            let n = s.length;
 
            // The pre is used to store the count of 0s
            // encountered from start to i index
 
            // The post is used to store the count of 1s
            // encountered from n-1 index to i index
            let pre = new Array(n).fill(0), post = new Array(n).fill(0);
 
            if (s[0] == '0')
                pre[0] = 1;
 
            // Loop to calculate the value of pre[i]
            for (let i = 1; i < n; i++) {
                if (s[i] == '0')
                    pre[i] = pre[i - 1] + 1;
                else
                    pre[i] = pre[i - 1];
            }
 
            if (s[n - 1] == '1')
                post[n - 1] = 1;
 
            // Loop to calculate the value of post[i]
            for (let i = n - 2; i >= 0; i--) {
                if (s[i] == '1')
                    post[i] = 1 + post[i + 1];
                else
                    post[i] = post[i + 1];
            }
 
            // Picking up the maximum possible length
            let ans = 0;
            for (let i = 0; i < n; i++) {
                ans = Math.max(ans, 2 * Math.min(pre[i], post[i]));
            }
 
            // Return the maximum length as answer
            return ans;
        }
 
        // Driver code
 
        let S = "0011001111";
 
        // Function call
        document.write(longestGoodString(S));
 
        // This code is contributed by rakeshsahni
 
    </script>


Output

8

Time Complexity: O(N) where N is the length of the String
Auxiliary Space: O(N) 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads