Related Articles
Longest increasing subsequence which forms a subarray in the sorted representation of the array
• Difficulty Level : Hard
• Last Updated : 14 Jun, 2021

Given an array arr[] of N integers, the task is to find the length of the longest increasing subsequence such that it forms a subarray when the original array is sorted.

Examples:

Input: arr[] = { 2, 6, 4, 8, 2, 9 }
Output: 3
Explanation:
Sorted array: {2, 2, 4, 6, 8, 9}
All possible non-decreasing sequences of the original array are
{2}, {6}, {4}, {8}, {2}, {9}, {2, 2}, {6, 8}, {8, 9}, {6, 8, 9}.
Out of all the above subsequences, {6, 8, 9} is the longest subsequence which is a subarray in the sorted representation of the array.

Input: arr[] = { 5, 5, 6, 6, 5, 5, 5, 6, 5, 5 }
Output: 7
Explanation:
Sorted array: {5, 5, 5, 5, 5, 5, 5, 6, 6, 6}
{5, 5, 5, 5, 5, 5, 5} is the longest subequence which forms a subarray in the sorted form of the array.

Naive Approach: The idea is to generate all the possible subsequences of the array and then to check which one of them forms the longest subarray when the original array is sorted.

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

Efficient Approach: The idea is to use Dynamic Programing approach to solve this problem. Below are the steps:

1. Store the frequency of each element in the given array in a Map.
2. Store the original array in a temporary array and sort the given array.
3. Initialise a 2D array of size N*3 where:
• dp[N][i] will store count of numbers X till position i.
• dp[x][1] will store count of number X + count of numbers (X – 1) till position i.
• dp[x][2] will store the actual length of sequence till position i.
4. Iterate over the original array and for each index i in the original array, include the element at the current position i only when all the (X â€“ 1) elements are already included in the subsequence and update the values in dp[][] and update the maximum subsequence size after this state.
5. Print the maximum subsequence size after completing the above steps.

Below is the implementation of the above approach:

## C++

 `// C++ program to implement``// the above approach` `#include ``using` `namespace` `std;` `// Function to find the length of the``// longest increasing sorted sequence``int` `LongestSequence(``int` `a[], ``int` `n)``{``    ``// Stores the count of all elements``    ``map<``int``, ``int``> m;` `    ``int` `ar[n + 1], i, j;` `    ``// Store the original array``    ``for` `(i = 1; i <= n; i++) {``        ``ar[i] = a[i - 1];``    ``}` `    ``// Sort the array``    ``sort(a, a + n);` `    ``int` `c = 1;``    ``m[a[0]] = c;` `    ``for` `(i = 1; i <= n; i++) {` `        ``// If adjacent element``        ``// are not same``        ``if` `(a[i] != a[i - 1]) {` `            ``// Increment count``            ``c++;``            ``m[a[i]] = c;``        ``}``    ``}` `    ``// Store frequency of each element``    ``map<``int``, ``int``> cnt;` `    ``// Initialize a DP array``    ``int` `dp[n + 1][3] = { 0 };``    ``cnt[0] = 0;` `    ``// Iterate over the array ar[]``    ``for` `(i = 1; i <= n; i++) {``        ``ar[i] = m[ar[i]];``        ``cnt[ar[i]]++;``    ``}` `    ``// Length of the longest``    ``// increasing sorted sequence``    ``int` `ans = 0, x;` `    ``// Iterate over the array``    ``for` `(i = 1; i <= n; i++) {` `        ``// Current element``        ``x = ar[i];` `        ``// If the element has been``        ``// encountered the first time``        ``if` `(dp[x][0] == 0) {` `            ``// If all the x - 1 previous``            ``// elements have already appeared``            ``if` `(dp[x - 1][0] == cnt[x - 1]) {``                ``dp[x][1] = dp[x - 1][1];``                ``dp[x][2] = dp[x - 1][1];``            ``}` `            ``// Otherwise``            ``else` `{``                ``dp[x][1] = dp[x - 1][0];``            ``}``        ``}` `        ``dp[x][2] = max(dp[x - 1][0],``                       ``dp[x][2]);` `        ``if` `(dp[x - 1][0] == cnt[x - 1]) {` `            ``// If all x-1 elements have``            ``// already been encountered``            ``dp[x][2] = max(dp[x][2],``                           ``dp[x - 1][1]);``        ``}``        ``for` `(j = 0; j < 3; j++) {` `            ``// Increment the count of``            ``// the current element``            ``dp[x][j]++;` `            ``// Update maximum``            ``// subsequence size``            ``ans = max(ans, dp[x][j]);``        ``}``    ``}` `    ``// Return the maximum``    ``// subsequence size``    ``return` `ans;``}` `// Driver Code``int` `main()``{``    ``int` `arr[] = { 2, 6, 4, 8, 2, 9 };` `    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr[0]);` `    ``// Function Call``    ``cout << LongestSequence(arr, N);``    ``return` `0;``}`

## Java

 `// Java program to implement``// the above approach``import` `java.io.*;``import` `java.util.*;` `class` `GFG{``    ` `// Function to find the length of the``// longest increasing sorted sequence``static` `int` `LongestSequence(``int` `a[], ``int` `n)``{``    ` `    ``// Stores the count of all elements``    ``HashMap m = ``new` `HashMap<>();``    ` `    ``int` `ar[] = ``new` `int``[n + ``1``];``    ``int` `i = ``0``;``    ``int` `j = ``0``;` `    ``// Store the original array``    ``for``(i = ``1``; i <= n; i++)``    ``{``        ``ar[i] = a[i - ``1``];``    ``}` `    ``// Sort the array``    ``Arrays.sort(a);``    ` `    ``int` `c = ``1``;``    ``m.put(a[``0``], c);` `    ``for``(i = ``1``; i < n; i++)``    ``{``        ` `        ``// If adjacent element``        ``// are not same``        ``if` `(a[i] != a[i - ``1``])``        ``{``            ` `            ``// Increment count``            ``c++;``            ``m.put(a[i], c);``        ``}``    ``}` `    ``// Store frequency of each element``    ``HashMap cnt = ``new` `HashMap<>();``    ` `    ``// Initialize a DP array``    ``int` `dp[][] = ``new` `int``[n + ``1``][``3``];` `    ``cnt.put(``0``, ``0``);` `    ``// Iterate over the array ar[]``    ``for``(i = ``1``; i <= n; i++)``    ``{``        ``ar[i] = m.get(ar[i]);``        ` `        ``if` `(cnt.containsKey(ar[i]))``            ``cnt.put(ar[i], cnt.get(ar[i]) + ``1``);``        ``else``            ``cnt.put(ar[i], ``1``);``    ``}` `    ``// Length of the longest``    ``// increasing sorted sequence``    ``int` `ans = ``0``, x;` `    ``// Iterate over the array``    ``for``(i = ``1``; i <= n; i++)``    ``{``        ` `        ``// Current element``        ``x = ar[i];` `        ``// If the element has been``        ``// encountered the first time``        ``if` `(dp[x][``0``] == ``0``)``        ``{``            ` `            ``// If all the x - 1 previous``            ``// elements have already appeared``            ``if` `(dp[x - ``1``][``0``] == cnt.get(x - ``1``))``            ``{``                ``dp[x][``1``] = dp[x - ``1``][``1``];``                ``dp[x][``2``] = dp[x - ``1``][``1``];``            ``}` `            ``// Otherwise``            ``else``            ``{``                ``dp[x][``1``] = dp[x - ``1``][``0``];``            ``}``        ``}``        ` `        ``dp[x][``2``] = Math.max(dp[x - ``1``][``0``],``                            ``dp[x][``2``]);` `        ``if` `(dp[x - ``1``][``0``] == cnt.get(x - ``1``))``        ``{``            ` `            ``// If all x-1 elements have``            ``// already been encountered``            ``dp[x][``2``] = Math.max(dp[x][``2``],``                                ``dp[x - ``1``][``1``]);``        ``}``        ``for``(j = ``0``; j < ``3``; j++)``        ``{` `            ``// Increment the count of``            ``// the current element``            ``dp[x][j]++;` `            ``// Update maximum``            ``// subsequence size``            ``ans = Math.max(ans, dp[x][j]);``        ``}``    ``}``    ` `    ``// Return the maximum``    ``// subsequence size``    ``return` `ans;``}` `// Driver code``public` `static` `void` `main(String[] args)``{``    ``int` `arr[] = { ``2``, ``6``, ``4``, ``8``, ``2``, ``9` `};``    ``int` `n = arr.length;``    ` `    ``System.out.println(LongestSequence(arr, n));``}``}` `// This code is contributed by bikram2001jha`

## Python3

 `# Python 3 program to implement``# the above approach` `# Function to find the length of the``# longest increasing sorted sequence``def` `LongestSequence(a, n):``  ` `  ``# Stores the count of all elements``  ``m ``=` `{i : ``0` `for` `i ``in` `range``(``100``)}` `  ``ar ``=` `[``0` `for` `i ``in` `range``(n ``+` `1``)]` `  ``# Store the original array``  ``for` `i ``in` `range``(``1``, n ``+` `1``):``    ``ar[i] ``=` `a[i ``-` `1``]` `  ``# Sort the array``  ``a.sort(reverse ``=` `False``)` `  ``c ``=` `1``  ``m[a[``0``]] ``=` `c` `  ``for` `i ``in` `range``(``1``, n):``    ` `    ``# If adjacent element``    ``# are not same``    ``if` `(a[i] !``=` `a[i ``-` `1``]):``      ` `      ``# Increment count``      ``c ``+``=` `1``      ``m[a[i]] ``=` `c` `  ``# Store frequency of each element``  ``cnt ``=` `{i : ``0` `for` `i ``in` `range``(``100``)}` `  ``# Initialize a DP array``  ``dp ``=` `[[``0` `for` `i ``in` `range``(``3``)]``           ``for` `j ``in` `range``(n ``+` `1``)]``  ` `  ``cnt[``0``] ``=` `0` `  ``# Iterate over the array ar[]``  ``for` `i ``in` `range``(``1``, n ``+` `1``):``    ` `    ``ar[i] ``=` `m[ar[i]]``    ``cnt[ar[i]] ``+``=` `1` `  ``# Length of the longest``  ``# increasing sorted sequence``  ``ans ``=` `0` `  ``# Iterate over the array``  ``for` `i ``in` `range``(``1``, n ``+` `1``):``    ` `    ``# Current element``    ``x ``=` `ar[i]` `    ``# If the element has been``    ``# encountered the first time``    ``if` `(dp[x][``0``] ``=``=` `0``):``      ` `      ``# If all the x - 1 previous``      ``# elements have already appeared``      ``if` `(dp[x ``-` `1``][``0``] ``=``=` `cnt[x ``-` `1``]):``        ``dp[x][``1``] ``=` `dp[x ``-` `1``][``1``]``        ``dp[x][``2``] ``=` `dp[x ``-` `1``][``1``]` `      ``# Otherwise``      ``else``:``        ``dp[x][``1``] ``=` `dp[x ``-` `1``][``0``]` `      ``dp[x][``2``] ``=` `max``(dp[x ``-` `1``][``0``], dp[x][``2``])` `      ``if` `(dp[x ``-` `1``][``0``] ``=``=` `cnt[x ``-` `1``]):``        ` `        ``# If all x-1 elements have``        ``# already been encountered``        ``dp[x][``2``] ``=` `max``(dp[x][``2``], dp[x ``-` `1``][``1``])``        ` `      ``for` `j ``in` `range``(``3``):``        ` `        ``# Increment the count of``        ``# the current element``        ``dp[x][j] ``+``=` `1` `        ``# Update maximum``        ``# subsequence size``        ``ans ``=` `max``(ans, dp[x][j])` `  ``# Return the maximum``  ``# subsequence size``  ``return` `ans` `# Driver Code``if` `__name__ ``=``=` `'__main__'``:``  ` `  ``arr ``=`  `[ ``2``, ``6``, ``4``, ``8``, ``2``, ``9` `]` `  ``N ``=` `len``(arr)` `  ``# Function call``  ``print``(LongestSequence(arr, N))``  ` `# This code is contributed by SURENDRA_GANGWAR`

## C#

 `// C# program to implement``// the above approach``using` `System.Collections.Generic;``using` `System;` `class` `GFG{``    ` `// Function to find the length of the``// longest increasing sorted sequence``static` `int` `LongestSequence(``int` `[]a, ``int` `n)``{``    ` `    ``// Stores the count of all elements``    ``Dictionary<``int``,``               ``int``> m = ``new` `Dictionary<``int``,``                                       ``int``>();``                                       ` `    ``int` `[]ar = ``new` `int``[n + 1];``    ``int` `i = 0;``    ``int` `j = 0;` `    ``// Store the original array``    ``for``(i = 1; i <= n; i++)``    ``{``        ``ar[i] = a[i - 1];``    ``}` `    ``// Sort the array``    ``Array.Sort(a);``    ` `    ``int` `c = 1;``    ``m[a[0]]= c;` `    ``for``(i = 1; i < n; i++)``    ``{``        ` `        ``// If adjacent element``        ``// are not same``        ``if` `(a[i] != a[i - 1])``        ``{``            ` `            ``// Increment count``            ``c++;``            ``m[a[i]]= c;``        ``}``    ``}` `    ``// Store frequency of each element``    ``Dictionary<``int``,``               ``int``>cnt = ``new` `Dictionary<``int``,``                                        ``int``>();``    ` `    ``// Initialize a DP array``    ``int` `[,]dp = ``new` `int``[n + 1, 3];` `    ``cnt[0] = 0;` `    ``// Iterate over the array ar[]``    ``for``(i = 1; i <= n; i++)``    ``{``        ``ar[i] = m[ar[i]];``        ` `        ``if` `(cnt.ContainsKey(ar[i]))``            ``cnt[ar[i]]= cnt[ar[i]] + 1;``        ``else``            ``cnt[ar[i]]= 1;``    ``}` `    ``// Length of the longest``    ``// increasing sorted sequence``    ``int` `ans = 0, x;` `    ``// Iterate over the array``    ``for``(i = 1; i <= n; i++)``    ``{``        ` `        ``// Current element``        ``x = ar[i];` `        ``// If the element has been``        ``// encountered the first time``        ``if` `(dp[x, 0] == 0)``        ``{``            ` `            ``// If all the x - 1 previous``            ``// elements have already appeared``            ``if` `(dp[x - 1, 0] == cnt[x - 1])``            ``{``                ``dp[x, 1] = dp[x - 1, 1];``                ``dp[x, 2] = dp[x - 1, 1];``            ``}` `            ``// Otherwise``            ``else``            ``{``                ``dp[x, 1] = dp[x - 1, 0];``            ``}``        ``}``        ` `        ``dp[x, 2] = Math.Max(dp[x - 1, 0],``                            ``dp[x, 2]);` `        ``if` `(dp[x - 1, 0] == cnt[x - 1])``        ``{``            ` `            ``// If all x-1 elements have``            ``// already been encountered``            ``dp[x, 2] = Math.Max(dp[x, 2],``                                ``dp[x - 1, 1]);``        ``}``        ``for``(j = 0; j < 3; j++)``        ``{` `            ``// Increment the count of``            ``// the current element``            ``dp[x, j]++;` `            ``// Update maximum``            ``// subsequence size``            ``ans = Math.Max(ans, dp[x, j]);``        ``}``    ``}``    ` `    ``// Return the maximum``    ``// subsequence size``    ``return` `ans;``}` `// Driver code``public` `static` `void` `Main()``{``    ``int` `[]arr = { 2, 6, 4, 8, 2, 9 };``    ``int` `n = arr.Length;``    ` `    ``Console.WriteLine(LongestSequence(arr, n));``}``}` `// This code is contributed by Stream_Cipher`

## Javascript

 ``
Output:
`3`

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

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with industry experts, please refer Geeks Classes Live

My Personal Notes arrow_drop_up