Open In App

Longest Non-Increasing Subsequence in a Binary String

Last Updated : 21 May, 2021
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a binary string S of size N, the task is to find the length of the longest non-increasing subsequence in the given string S.

Examples:

Input: S = "0101110110100001011"
Output: 12 
Explanation: The longest non-increasing subsequence is "111111100000", having length equal to 12.

Input: S = 10101
Output: 3

Approach: The given problem can be solved based on the observation that the string S is a binary string, so a non-increasing subsequence will always consist of 0 with more consecutive 1s or 1 with more consecutive 0s. Follow the steps below to solve the problem:

  • Initialize an array, say pre[], that stores the number of 1s till each index i for i is over the range [0, N - 1].
  • Initialize an array, say post[], that stores the number of 0s till each index i to the end of the string for i over the range [0, N - 1].
  • Initialize a variable, say ans that stores the length of the longest non-increasing subsequence in the given string S.
  • Iterate over the range [0, N - 1] and update the value of ans to the maximum of ans and (pre[i] + post[i]).
  • After completing the above steps, print the value of ans as the result.

Below is the implementation of the above approach:

C++
// C++ program for the above approach

#include <bits/stdc++.h>
using namespace std;

// Function to find the length of the
// longest non-increasing subsequence
int findLength(string str, int n)
{
    // Stores the prefix and suffix
    // count of 1s and 0s respectively
    int pre[n], post[n];

    // Initialize the array
    memset(pre, 0, sizeof(pre));
    memset(post, 0, sizeof(post));

    // Store the number of '1's
    // up to current index i in pre
    for (int i = 0; i < n; i++) {

        // Find the prefix sum
        if (i != 0) {
            pre[i] += pre[i - 1];
        }

        // If the current element
        // is '1', update the pre[i]
        if (str[i] == '1') {
            pre[i] += 1;
        }
    }

    // Store the number of '0's over
    // the range [i, N - 1]
    for (int i = n - 1; i >= 0; i--) {

        // Find the suffix sum
        if (i != n - 1)
            post[i] += post[i + 1];

        // If the current element
        // is '0', update post[i]
        if (str[i] == '0')
            post[i] += 1;
    }

    // Stores the maximum length
    int ans = 0;

    // Find the maximum value of
    // pre[i] + post[i]
    for (int i = 0; i < n; i++) {
        ans = max(ans, pre[i] + post[i]);
    }

    // Return the answer
    return ans;
}

// Driver Code
int main()
{
    string S = "0101110110100001011";
    cout << findLength(S, S.length());

    return 0;
}
Java
// Java program for the above approach
class GFG{

// Function to find the length of the
// longest non-increasing subsequence
static int findLength(String str, int n)
{
    
    // Stores the prefix and suffix
    // count of 1s and 0s respectively
    int pre[] = new int[n];
    int post[] = new int[n];

    // Initialize the array
    for(int i = 0; i < n; i++) 
    {
        pre[i] = 0;
        post[i] = 0;
    }

    // Store the number of '1's
    // up to current index i in pre
    for(int i = 0; i < n; i++) 
    {
        
        // Find the prefix sum
        if (i != 0) 
        {
            pre[i] += pre[i - 1];
        }

        // If the current element
        // is '1', update the pre[i]
        if (str.charAt(i) == '1')
        {
            pre[i] += 1;
        }
    }

    // Store the number of '0's over
    // the range [i, N - 1]
    for(int i = n - 1; i >= 0; i--) 
    {
        
        // Find the suffix sum
        if (i != n - 1)
            post[i] += post[i + 1];

        // If the current element
        // is '0', update post[i]
        if (str.charAt(i) == '0')
            post[i] += 1;
    }

    // Stores the maximum length
    int ans = 0;

    // Find the maximum value of
    // pre[i] + post[i]
    for(int i = 0; i < n; i++)
    {
        ans = Math.max(ans, pre[i] + post[i]);
    }

    // Return the answer
    return ans;
}

// Driver Code
public static void main(String[] args)
{
    String S = "0101110110100001011";
    System.out.println(findLength(S, S.length()));
}
}

// This code is contributed by abhinavjain194
Python3
# Python3 program for the above approach

# Function to find the length of the
# longest non-increasing subsequence
def findLength(str, n):
    
    # Stores the prefix and suffix
    # count of 1s and 0s respectively
    pre = [0] * n
    post  = [0] * n

    # Store the number of '1's
    # up to current index i in pre
    for i in range(n):

        # Find the prefix sum
        if (i != 0):
            pre[i] += pre[i - 1]
    
        # If the current element
        # is '1', update the pre[i]
        if (str[i] == '1'):
            pre[i] += 1
        
    # Store the number of '0's over
    # the range [i, N - 1]
    for i in range(n - 1, -1, -1): 

        # Find the suffix sum
        if (i != (n - 1)):
            post[i] += post[i + 1]

        # If the current element
        # is '0', update post[i]
        if (str[i] == '0'):
            post[i] += 1
    
    # Stores the maximum length
    ans = 0

    # Find the maximum value of
    # pre[i] + post[i]
    for i in range(n):
        ans = max(ans, pre[i] + post[i])
    
    # Return the answer
    return ans

# Driver Code
S = "0101110110100001011"
n = len(S)

print(findLength(S, n))

# This code is contributed by susmitakundugoaldanga
C#
// C# program for the above approach
using System;

class GFG{

// Function to find the length of the
// longest non-increasing subsequence
static int findLength(String str, int n)
{
    
    // Stores the prefix and suffix
    // count of 1s and 0s respectively
    int []pre = new int[n];
    int []post = new int[n];

    // Initialize the array
    for(int i = 0; i < n; i++) 
    {
        pre[i] = 0;
        post[i] = 0;
    }

    // Store the number of '1's
    // up to current index i in pre
    for(int i = 0; i < n; i++) 
    {
        
        // Find the prefix sum
        if (i != 0) 
        {
            pre[i] += pre[i - 1];
        }

        // If the current element
        // is '1', update the pre[i]
        if (str[i] == '1')
        {
            pre[i] += 1;
        }
    }

    // Store the number of '0's over
    // the range [i, N - 1]
    for(int i = n - 1; i >= 0; i--) 
    {
        
        // Find the suffix sum
        if (i != n - 1)
            post[i] += post[i + 1];

        // If the current element
        // is '0', update post[i]
        if (str[i] == '0')
            post[i] += 1;
    }

    // Stores the maximum length
    int ans = 0;

    // Find the maximum value of
    // pre[i] + post[i]
    for(int i = 0; i < n; i++)
    {
        ans = Math.Max(ans, pre[i] + post[i]);
    }

    // Return the answer
    return ans;
}

// Driver Code
public static void Main(String[] args)
{
    String S = "0101110110100001011";
    Console.WriteLine(findLength(S, S.Length));
}
}

// This code is contributed by Princi Singh 
JavaScript
<script>

// Javascript program for the above approach

// Function to find the length of the
// longest non-increasing subsequence
function findLength(str, n)
{
    
    // Stores the prefix and suffix
    // count of 1s and 0s respectively
    let pre = Array.from({length: n}, (_, i) => 0);
    let post = Array.from({length: n}, (_, i) => 0);

    // Initialize the array
    for(let i = 0; i < n; i++) 
    {
        pre[i] = 0;
        post[i] = 0;
    }

    // Store the number of '1's
    // up to current index i in pre
    for(let i = 0; i < n; i++) 
    {
        
        // Find the prefix sum
        if (i != 0) 
        {
            pre[i] += pre[i - 1];
        }

        // If the current element
        // is '1', update the pre[i]
        if (str[i] == '1')
        {
            pre[i] += 1;
        }
    }

    // Store the number of '0's over
    // the range [i, N - 1]
    for(let i = n - 1; i >= 0; i--) 
    {
        
        // Find the suffix sum
        if (i != n - 1)
            post[i] += post[i + 1];

        // If the current element
        // is '0', update post[i]
        if (str[i] == '0')
            post[i] += 1;
    }

    // Stores the maximum length
    let ans = 0;

    // Find the maximum value of
    // pre[i] + post[i]
    for(let i = 0; i < n; i++)
    {
        ans = Math.max(ans, pre[i] + post[i]);
    }

    // Return the answer
    return ans;
}

// Driver Code
    
    let S = "0101110110100001011";
    document.write(findLength(S, S.length));
      
</script>

Output: 
12

 

Time Complexity: O(N)
Auxiliary Space: O(N)


Next Article

Similar Reads