Skip to content
geeksforgeeks
  • Courses
    • DSA to Development
    • Get IBM Certification
    • Newly Launched!
      • Master Django Framework
      • Become AWS Certified
    • For Working Professionals
      • Interview 101: DSA & System Design
      • Data Science Training Program
      • JAVA Backend Development (Live)
      • DevOps Engineering (LIVE)
      • Data Structures & Algorithms in Python
    • For Students
      • Placement Preparation Course
      • Data Science (Live)
      • Data Structure & Algorithm-Self Paced (C++/JAVA)
      • Master Competitive Programming (Live)
      • Full Stack Development with React & Node JS (Live)
    • Full Stack Development
    • Data Science Program
    • All Courses
  • Tutorials
    • Data Structures & Algorithms
    • ML & Data Science
    • Interview Corner
    • Programming Languages
    • Web Development
    • CS Subjects
    • DevOps And Linux
    • School Learning
  • Practice
    • Build your AI Agent
    • GfG 160
    • Problem of the Day
    • Practice Coding Problems
    • GfG SDE Sheet
  • Contests
    • Accenture Hackathon (Ending Soon!)
    • GfG Weekly [Rated Contest]
    • Job-A-Thon Hiring Challenge
    • All Contests and Events
  • DSA
  • Interview Problems on DP
  • Practice DP
  • MCQs on DP
  • Tutorial on Dynamic Programming
  • Optimal Substructure
  • Overlapping Subproblem
  • Memoization
  • Tabulation
  • Tabulation vs Memoization
  • 0/1 Knapsack
  • Unbounded Knapsack
  • Subset Sum
  • LCS
  • LIS
  • Coin Change
  • Word Break
  • Egg Dropping Puzzle
  • Matrix Chain Multiplication
  • Palindrome Partitioning
  • DP on Arrays
  • DP with Bitmasking
  • Digit DP
  • DP on Trees
  • DP on Graph
Open In App
Next Article:
Maximum length of Strictly Increasing Sub-array after removing at most one element
Next article icon

Maximize length of Non-Decreasing Subsequence by reversing at most one Subarray

Last Updated : 29 Mar, 2023
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a binary array arr[], the task is to find the maximum possible length of non-decreasing subsequence that can be generated by reversing a subarray at most once.

Examples:

Input: arr[] = {0, 1, 0, 1} 
Output: 4 
Explanation: 
After reversing the subarray from index [2, 3], the array modifies to {0, 0, 1, 1}. 
Hence, the longest non-decreasing subsequence is {0, 0, 1, 1}.

Input: arr[] = {0, 1, 1, 1, 0, 0, 1, 1, 0} 
Output: 9 
Explanation: 
After reversing the subarray from index [2, 6], the array modifies to {0, 0, 0, 1, 1, 1, 1, 1, 0}. 
Hence, the longest non-decreasing subsequence is {0, 0, 0, 1, 1, 1, 1, 1}.

Naive Approach: The simplest approach to solve the problem is to reverse each possible subarray in the given array, and find the longest non-decreasing subsequence possible from the array after reversing the subarray.

Time Complexity: O(N3) 
Auxiliary Space: O(N)
Efficient Approach: The idea is to use Dynamic Programming to solve the problem. Follow the steps below: 
 

  • Since the array is a binary array the idea is to find the longest subsequence among the subsequences of the forms {0….0}, {0…1…}, {0..1..0…}, 0..1..0..1.
  • Initialize a dynamic programming table as dp[][] which stores the following:

 
 

dp[i][0] : Stores the length of the longest subsequence (0..) from a[0 to i]. 
dp[i][1] : Stores the length of the longest subsequence (0..1..) from a[0 to i]. 
dp[i][2] : Stores the length of the longest subsequence (0..1..0..) from a[0 to i]. 
dp[i][3] : Stores the length of the longest subsequence (0..1..0..1..) from a[0 to i].

 

  • Therefore, the answer is the longest subsequence or the maximum of all the 4 given possibilities ( dp[n-1][0], d[n-1][1], dp[n-1][2], dp[n-1][3] ).

Below is the implementation of the above approach:
 

C++




// C++ program to implement
// the above approach
#include<bits/stdc++.h>
using namespace std;
 
// Function to find the maximum length
// non decreasing subarray by reversing
// at most one subarray
void main_fun(int arr[], int n)
{
 
    // dp[i][j] be the longest
    // subsequence of a[0...i]
    // with first j parts
    int dp[4][n];
    memset(dp, 0, sizeof(dp[0][0] * 4 * n));
 
    if (arr[0] == 0)
        dp[0][0] = 1;
    else
        dp[1][0] = 1;
 
    // Maximum length sub-sequence
    // of (0..)
    for(int i = 1; i < n; i++)
    {
        if (arr[i] == 0)
            dp[0][i] = dp[0][i - 1] + 1;
        else
            dp[0][i] = dp[0][i - 1];
    }
 
    // Maximum length sub-sequence
    // of (0..1..)
    for(int i = 1; i < n; i++)
    {
        if (arr[i] == 1)
            dp[1][i] = max(dp[1][i - 1] + 1,
                           dp[0][i - 1] + 1);
        else
            dp[1][i] = dp[1][i - 1];
    }
 
    // Maximum length sub-sequence
    // of (0..1..0..)
    for(int i = 1; i < n; i++)
    {
        if (arr[i] == 0)
        {
            dp[2][i] = max(dp[2][i - 1] + 1,
                           max(dp[1][i - 1] + 1,
                               dp[0][i - 1] + 1));
        }
        else
            dp[2][i] = dp[2][i - 1];
    }
 
    // Maximum length sub-sequence
    // of (0..1..0..1..)
    for(int i = 1; i < n; i++)
    {
        if (arr[i] == 1)
        {
            dp[3][i] = max(dp[3][i - 1] + 1,
                            max(dp[2][i - 1] + 1,
                                max(dp[1][i - 1] + 1,
                                    dp[0][i - 1] + 1)));
        }
        else
            dp[3][i] = dp[3][i - 1];
    }
 
    // Find the max length subsequence
    int ans = max(dp[2][n - 1], max(dp[1][n - 1],
              max(dp[0][n - 1], dp[3][n - 1])));
 
    // Print the answer
    cout << (ans);
}
 
// Driver Code
int main()
{
    int n = 4;
    int arr[] = {0, 1, 0, 1};
     
    main_fun(arr, n);
    return 0;
}
 
// This code is contributed by chitranayal
 
 

Java




// Java program to implement
// the above approach
import java.util.*;
 
class GFG{
 
// Function to find the maximum length
// non decreasing subarray by reversing
// at most one subarray
static void main_fun(int arr[], int n)
{
     
    // dp[i][j] be the longest
    // subsequence of a[0...i]
    // with first j parts
    int[][] dp = new int[4][n];
 
    if (arr[0] == 0)
        dp[0][0] = 1;
    else
        dp[1][0] = 1;
 
    // Maximum length sub-sequence
    // of (0..)
    for(int i = 1; i < n; i++)
    {
        if (arr[i] == 0)
            dp[0][i] = dp[0][i - 1] + 1;
        else
            dp[0][i] = dp[0][i - 1];
    }
 
    // Maximum length sub-sequence
    // of (0..1..)
    for(int i = 1; i < n; i++)
    {
        if (arr[i] == 1)
            dp[1][i] = Math.max(dp[1][i - 1] + 1,
                                dp[0][i - 1] + 1);
        else
            dp[1][i] = dp[1][i - 1];
    }
 
    // Maximum length sub-sequence
    // of (0..1..0..)
    for(int i = 1; i < n; i++)
    {
        if (arr[i] == 0)
        {
            dp[2][i] = Math.max(dp[2][i - 1] + 1,
                       Math.max(dp[1][i - 1] + 1,
                                dp[0][i - 1] + 1));
        }
        else
            dp[2][i] = dp[2][i - 1];
    }
 
    // Maximum length sub-sequence
    // of (0..1..0..1..)
    for(int i = 1; i < n; i++)
    {
        if (arr[i] == 1)
        {
            dp[3][i] = Math.max(dp[3][i - 1] + 1,
                       Math.max(dp[2][i - 1] + 1,
                       Math.max(dp[1][i - 1] + 1,
                                dp[0][i - 1] + 1)));
        }
        else
            dp[3][i] = dp[3][i - 1];
    }
 
    // Find the max length subsequence
    int ans = Math.max(dp[2][n - 1],
              Math.max(dp[1][n - 1],
              Math.max(dp[0][n - 1],
                       dp[3][n - 1])));
 
    // Print the answer
    System.out.print(ans);
}
 
// Driver code
public static void main (String[] args)
{
    int n = 4;
    int arr[] = { 0, 1, 0, 1 };
     
    main_fun(arr, n);
}
}
 
// This code is contributed by offbeat
 
 

Python3




# Python3 program to implement
# the above approach
import sys
 
# Function to find the maximum length
# non decreasing subarray by reversing
# at most one subarray
def main(arr, n):
 
    # dp[i][j] be the longest
    # subsequence of a[0...i]
    # with first j parts
    dp = [[0 for x in range(n)] for y in range(4)]
 
    if arr[0] == 0:
        dp[0][0] = 1
    else:
        dp[1][0] = 1
 
    # Maximum length sub-sequence
    # of (0..)
    for i in range(1, n):
        if arr[i] == 0:
            dp[0][i] = dp[0][i-1] + 1
        else:
            dp[0][i] = dp[0][i-1]
 
    # Maximum length sub-sequence
    # of (0..1..)
    for i in range(1, n):
        if arr[i] == 1:
            dp[1][i] = max(dp[1][i-1] + 1, dp[0][i-1] + 1)
        else:
            dp[1][i] = dp[1][i-1]
 
    # Maximum length sub-sequence
    # of (0..1..0..)
    for i in range(1, n):
        if arr[i] == 0:
            dp[2][i] = max([dp[2][i-1] + 1,
                            dp[1][i-1] + 1,
                            dp[0][i-1] + 1])
        else:
            dp[2][i] = dp[2][i-1]
 
    # Maximum length sub-sequence
    # of (0..1..0..1..)
    for i in range(1, n):
        if arr[i] == 1:
            dp[3][i] = max([dp[3][i-1] + 1,
                            dp[2][i-1] + 1,
                            dp[1][i-1] + 1,
                            dp[0][i-1] + 1])
        else:
            dp[3][i] = dp[3][i-1]
 
    # Find the max length subsequence
    ans = max([dp[2][n-1], dp[1][n-1],
            dp[0][n-1], dp[3][n-1]])
 
    # Print the answer
    print(ans)
 
 
# Driver Code
if __name__ == "__main__":
    n = 4
    arr = [0, 1, 0, 1]
    main(arr, n)
 
 

C#




// C# program to implement
// the above approach
using System;
 
class GFG{
 
// Function to find the maximum length
// non decreasing subarray by reversing
// at most one subarray
static void main_fun(int []arr, int n)
{
     
    // dp[i,j] be the longest
    // subsequence of a[0...i]
    // with first j parts
    int[,] dp = new int[4, n];
 
    if (arr[0] == 0)
        dp[0, 0] = 1;
    else
        dp[1, 0] = 1;
 
    // Maximum length sub-sequence
    // of (0..)
    for(int i = 1; i < n; i++)
    {
        if (arr[i] == 0)
            dp[0, i] = dp[0, i - 1] + 1;
        else
            dp[0, i] = dp[0, i - 1];
    }
 
    // Maximum length sub-sequence
    // of (0..1..)
    for(int i = 1; i < n; i++)
    {
        if (arr[i] == 1)
            dp[1, i] = Math.Max(dp[1, i - 1] + 1,
                                dp[0, i - 1] + 1);
        else
            dp[1, i] = dp[1, i - 1];
    }
 
    // Maximum length sub-sequence
    // of (0..1..0..)
    for(int i = 1; i < n; i++)
    {
        if (arr[i] == 0)
        {
            dp[2, i] = Math.Max(dp[2, i - 1] + 1,
                       Math.Max(dp[1, i - 1] + 1,
                                dp[0, i - 1] + 1));
        }
        else
            dp[2, i] = dp[2, i - 1];
    }
 
    // Maximum length sub-sequence
    // of (0..1..0..1..)
    for(int i = 1; i < n; i++)
    {
        if (arr[i] == 1)
        {
            dp[3, i] = Math.Max(dp[3, i - 1] + 1,
                       Math.Max(dp[2, i - 1] + 1,
                       Math.Max(dp[1, i - 1] + 1,
                                dp[0, i - 1] + 1)));
        }
        else
            dp[3, i] = dp[3, i - 1];
    }
 
    // Find the max length subsequence
    int ans = Math.Max(dp[2, n - 1],
              Math.Max(dp[1, n - 1],
              Math.Max(dp[0, n - 1],
                       dp[3, n - 1])));
 
    // Print the answer
    Console.Write(ans);
}
 
// Driver code
public static void Main(String[] args)
{
    int n = 4;
    int []arr = { 0, 1, 0, 1 };
     
    main_fun(arr, n);
}
}
 
// This code is contributed by Amit Katiyar 
 
 

Javascript




<script>
 
// JavaScript program to implement
// the above approach
 
// Function to find the maximum length
// non decreasing subarray by reversing
// at most one subarray
function main_fun(arr, n)
{
 
    // dp[i][j] be the longest
    // subsequence of a[0...i]
    // with first j parts
    var dp = Array.from(Array(4), ()=>Array(n).fill(0));
 
    if (arr[0] == 0)
        dp[0][0] = 1;
    else
        dp[1][0] = 1;
 
    // Maximum length sub-sequence
    // of (0..)
    for(var i = 1; i < n; i++)
    {
        if (arr[i] == 0)
            dp[0][i] = dp[0][i - 1] + 1;
        else
            dp[0][i] = dp[0][i - 1];
    }
 
    // Maximum length sub-sequence
    // of (0..1..)
    for(var i = 1; i < n; i++)
    {
        if (arr[i] == 1)
            dp[1][i] = Math.max(dp[1][i - 1] + 1,
                           dp[0][i - 1] + 1);
        else
            dp[1][i] = dp[1][i - 1];
    }
 
    // Maximum length sub-sequence
    // of (0..1..0..)
    for(var i = 1; i < n; i++)
    {
        if (arr[i] == 0)
        {
            dp[2][i] = Math.max(dp[2][i - 1] + 1,
                           Math.max(dp[1][i - 1] + 1,
                               dp[0][i - 1] + 1));
        }
        else
            dp[2][i] = dp[2][i - 1];
    }
 
    // Maximum length sub-sequence
    // of (0..1..0..1..)
    for(var i = 1; i < n; i++)
    {
        if (arr[i] == 1)
        {
            dp[3][i] = Math.max(dp[3][i - 1] + 1,
                            Math.max(dp[2][i - 1] + 1,
                                Math.max(dp[1][i - 1] + 1,
                                    dp[0][i - 1] + 1)));
        }
        else
            dp[3][i] = dp[3][i - 1];
    }
 
    // Find the max length subsequence
    var ans = Math.max(dp[2][n - 1], Math.max(dp[1][n - 1],
              Math.max(dp[0][n - 1], dp[3][n - 1])));
 
    // Print the answer
    document.write(ans);
}
 
// Driver Code
var n = 4;
var arr = [0, 1, 0, 1];
 
main_fun(arr, n);
 
</script>
 
 
Output: 
4

 

Time Complexity: O(N) 
Auxiliary Space: O(N) <= O(4*N)
 



Next Article
Maximum length of Strictly Increasing Sub-array after removing at most one element

K

kfardeen7890
Improve
Article Tags :
  • Arrays
  • Competitive Programming
  • DSA
  • Dynamic Programming
  • subarray
  • subsequence
Practice Tags :
  • Arrays
  • Dynamic Programming

Similar Reads

  • Maximize subarray sum by inverting sign of elements of any subarray at most twice
    Given an array A of size n, find the maximum subarray sum after applying the given operation at most two times. In one operation, choose any two indices i and j and invert sign of all the elements from index i to index j, i.e, all positive elements in the range i to j become negative and all negativ
    10 min read
  • Maximum length of Strictly Increasing Sub-array after removing at most one element
    Given an array arr[], the task is to remove at most one element and calculate the maximum length of strictly increasing subarray. Examples: Input: arr[] = {1, 2, 5, 3, 4} Output: 4 After deleting 5, the resulting array will be {1, 2, 3, 4} and the maximum length of its strictly increasing subarray i
    10 min read
  • Maximum sum of non-overlapping subarrays of length atmost K
    Given an integer array 'arr' of length N and an integer 'k', select some non-overlapping subarrays such that each sub-array if of length at most 'k', no two sub-arrays are adjacent and sum of all the elements of the selected sub-arrays are maximum.Examples: Input : arr[] = {-1, 2, -3, 4, 5}, k = 2 O
    10 min read
  • Maximize length of subarray of equal elements by performing at most K increment operations
    Given an array A[] consisting of N integers and an integer K, the task is to maximize the length of the subarray having equal elements after performing at most K increments by 1 on array elements. Note: Same array element can be incremented more than once. Examples: Input: A[] = {2, 4, 8, 5, 9, 6},
    8 min read
  • Maximize non decreasing Array size by replacing Subarray with sum
    Given an array arr[] of size N. In one operation only one subarray can be selected and replaced with the sum of the subarray. The task is to find the maximum size of the array after making it non-decreasing. Examples: Input: N = 5, arr[] = {5, 1, 6, 6, 6}Output: 4Explanation: maximum size non-decrea
    15+ min read
  • Maximum sum of at most K non-overlapping Subarray
    Given an array, arr[] of size N, the task is to find the sum of the at most K non-overlapping contiguous subarray within an arr[] with the maximum sum. Examples: Input: arr[] = [4, 1, -3, 7, -5, 6, -2, 1], K = 3Output: 18Explanation: In the above input, the maximum k subarray sum is 18 and the subar
    15 min read
  • Length of the longest increasing subsequence which does not contain a given sequence as Subarray
    Given two arrays arr[] and arr1[] of lengths N and M respectively, the task is to find the longest increasing subsequence of array arr[] such that it does not contain array arr1[] as subarray. Examples: Input: arr[] = {5, 3, 9, 3, 4, 7}, arr1[] = {3, 3, 7}Output: 4Explanation: Required longest incre
    14 min read
  • Maximize the maximum subarray sum after removing atmost one element
    Given an array arr[] of N integers, the task is to find the maximum sum of a subarray with at most one deletion allowed. The size of subarray to be considered should be at least 1. Examples: Input: arr[] = {1, 2, 3, -2, 3} Output: 9 The maximum sub-array sum is given by the sub-array {2, 3, -2, 3} H
    2 min read
  • Maximise array sum after taking non-overlapping sub-arrays of length K
    Given an integer array arr[] of length N and an integer K, the task is to select some non-overlapping sub-arrays such that each sub-array is exactly of length K, no two sub-arrays are adjacent and sum of all the elements of the selected sub-arrays is maximum.Examples: Input: arr[] = {1, 2, 3, 4, 5},
    8 min read
  • Maximize product of a strictly increasing or decreasing subarray
    Given an array arr[] of size N, the task is to find the maximum product from any subarray consisting of elements in strictly increasing or decreasing order. Examples: Input: arr[] = { 1, 2, 10, 8, 1, 100, 101 } Output: 10100 Explanation: Increasing subarray with maximum product is {1, 100, 101}. The
    14 min read
geeksforgeeks-footer-logo
Corporate & Communications Address:
A-143, 7th Floor, Sovereign Corporate Tower, Sector- 136, Noida, Uttar Pradesh (201305)
Registered Address:
K 061, Tower K, Gulshan Vivante Apartment, Sector 137, Noida, Gautam Buddh Nagar, Uttar Pradesh, 201305
GFG App on Play Store GFG App on App Store
Advertise with us
  • Company
  • About Us
  • Legal
  • Privacy Policy
  • In Media
  • Contact Us
  • Advertise with us
  • GFG Corporate Solution
  • Placement Training Program
  • Languages
  • Python
  • Java
  • C++
  • PHP
  • GoLang
  • SQL
  • R Language
  • Android Tutorial
  • Tutorials Archive
  • DSA
  • Data Structures
  • Algorithms
  • DSA for Beginners
  • Basic DSA Problems
  • DSA Roadmap
  • Top 100 DSA Interview Problems
  • DSA Roadmap by Sandeep Jain
  • All Cheat Sheets
  • Data Science & ML
  • Data Science With Python
  • Data Science For Beginner
  • Machine Learning
  • ML Maths
  • Data Visualisation
  • Pandas
  • NumPy
  • NLP
  • Deep Learning
  • Web Technologies
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • ReactJS
  • NextJS
  • Bootstrap
  • Web Design
  • Python Tutorial
  • Python Programming Examples
  • Python Projects
  • Python Tkinter
  • Python Web Scraping
  • OpenCV Tutorial
  • Python Interview Question
  • Django
  • Computer Science
  • Operating Systems
  • Computer Network
  • Database Management System
  • Software Engineering
  • Digital Logic Design
  • Engineering Maths
  • Software Development
  • Software Testing
  • DevOps
  • Git
  • Linux
  • AWS
  • Docker
  • Kubernetes
  • Azure
  • GCP
  • DevOps Roadmap
  • System Design
  • High Level Design
  • Low Level Design
  • UML Diagrams
  • Interview Guide
  • Design Patterns
  • OOAD
  • System Design Bootcamp
  • Interview Questions
  • Inteview Preparation
  • Competitive Programming
  • Top DS or Algo for CP
  • Company-Wise Recruitment Process
  • Company-Wise Preparation
  • Aptitude Preparation
  • Puzzles
  • School Subjects
  • Mathematics
  • Physics
  • Chemistry
  • Biology
  • Social Science
  • English Grammar
  • Commerce
  • World GK
  • GeeksforGeeks Videos
  • DSA
  • Python
  • Java
  • C++
  • Web Development
  • Data Science
  • CS Subjects
@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Lightbox
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

What kind of Experience do you want to share?

Interview Experiences
Admission Experiences
Career Journeys
Work Experiences
Campus Experiences
Competitive Exam Experiences