Longest increasing subsequence which forms a subarray in the sorted representation of the array
Last Updated :
12 Dec, 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 subsequence 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 Programming approach to solve this problem. Below are the steps:
- Store the frequency of each element in the given array in a Map.
- Store the original array in a temporary array and sort the given array.
- 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.
- 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.
- Print the maximum subsequence size after completing the above steps.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int LongestSequence( int a[], int n)
{
map< int , int > m;
int ar[n + 1], i, j;
for (i = 1; i <= n; i++) {
ar[i] = a[i - 1];
}
sort(a, a + n);
int c = 1;
m[a[0]] = c;
for (i = 1; i <= n; i++) {
if (a[i] != a[i - 1]) {
c++;
m[a[i]] = c;
}
}
map< int , int > cnt;
int dp[n + 1][3] = { 0 };
cnt[0] = 0;
for (i = 1; i <= n; i++) {
ar[i] = m[ar[i]];
cnt[ar[i]]++;
}
int ans = 0, x;
for (i = 1; i <= n; i++) {
x = ar[i];
if (dp[x][0] == 0) {
if (dp[x - 1][0] == cnt[x - 1]) {
dp[x][1] = dp[x - 1][1];
dp[x][2] = dp[x - 1][1];
}
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]) {
dp[x][2] = max(dp[x][2],
dp[x - 1][1]);
}
for (j = 0; j < 3; j++) {
dp[x][j]++;
ans = max(ans, dp[x][j]);
}
}
return ans;
}
int main()
{
int arr[] = { 2, 6, 4, 8, 2, 9 };
int N = sizeof (arr) / sizeof (arr[0]);
cout << LongestSequence(arr, N);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG{
static int LongestSequence( int a[], int n)
{
HashMap<Integer, Integer> m = new HashMap<>();
int ar[] = new int [n + 1 ];
int i = 0 ;
int j = 0 ;
for (i = 1 ; i <= n; i++)
{
ar[i] = a[i - 1 ];
}
Arrays.sort(a);
int c = 1 ;
m.put(a[ 0 ], c);
for (i = 1 ; i < n; i++)
{
if (a[i] != a[i - 1 ])
{
c++;
m.put(a[i], c);
}
}
HashMap<Integer, Integer> cnt = new HashMap<>();
int dp[][] = new int [n + 1 ][ 3 ];
cnt.put( 0 , 0 );
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 );
}
int ans = 0 , x;
for (i = 1 ; i <= n; i++)
{
x = ar[i];
if (dp[x][ 0 ] == 0 )
{
if (dp[x - 1 ][ 0 ] == cnt.get(x - 1 ))
{
dp[x][ 1 ] = dp[x - 1 ][ 1 ];
dp[x][ 2 ] = dp[x - 1 ][ 1 ];
}
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 ))
{
dp[x][ 2 ] = Math.max(dp[x][ 2 ],
dp[x - 1 ][ 1 ]);
}
for (j = 0 ; j < 3 ; j++)
{
dp[x][j]++;
ans = Math.max(ans, dp[x][j]);
}
}
return ans;
}
public static void main(String[] args)
{
int arr[] = { 2 , 6 , 4 , 8 , 2 , 9 };
int n = arr.length;
System.out.println(LongestSequence(arr, n));
}
}
|
Python3
def LongestSequence(a, n):
m = {i : 0 for i in range ( 100 )}
ar = [ 0 for i in range (n + 1 )]
for i in range ( 1 , n + 1 ):
ar[i] = a[i - 1 ]
a.sort(reverse = False )
c = 1
m[a[ 0 ]] = c
for i in range ( 1 , n):
if (a[i] ! = a[i - 1 ]):
c + = 1
m[a[i]] = c
cnt = {i : 0 for i in range ( 100 )}
dp = [[ 0 for i in range ( 3 )]
for j in range (n + 1 )]
cnt[ 0 ] = 0
for i in range ( 1 , n + 1 ):
ar[i] = m[ar[i]]
cnt[ar[i]] + = 1
ans = 0
for i in range ( 1 , n + 1 ):
x = ar[i]
if (dp[x][ 0 ] = = 0 ):
if (dp[x - 1 ][ 0 ] = = cnt[x - 1 ]):
dp[x][ 1 ] = dp[x - 1 ][ 1 ]
dp[x][ 2 ] = dp[x - 1 ][ 1 ]
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 ]):
dp[x][ 2 ] = max (dp[x][ 2 ], dp[x - 1 ][ 1 ])
for j in range ( 3 ):
dp[x][j] + = 1
ans = max (ans, dp[x][j])
return ans
if __name__ = = '__main__' :
arr = [ 2 , 6 , 4 , 8 , 2 , 9 ]
N = len (arr)
print (LongestSequence(arr, N))
|
C#
using System.Collections.Generic;
using System;
class GFG{
static int LongestSequence( int []a, int n)
{
Dictionary< int ,
int > m = new Dictionary< int ,
int >();
int []ar = new int [n + 1];
int i = 0;
int j = 0;
for (i = 1; i <= n; i++)
{
ar[i] = a[i - 1];
}
Array.Sort(a);
int c = 1;
m[a[0]]= c;
for (i = 1; i < n; i++)
{
if (a[i] != a[i - 1])
{
c++;
m[a[i]]= c;
}
}
Dictionary< int ,
int >cnt = new Dictionary< int ,
int >();
int [,]dp = new int [n + 1, 3];
cnt[0] = 0;
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;
}
int ans = 0, x;
for (i = 1; i <= n; i++)
{
x = ar[i];
if (dp[x, 0] == 0)
{
if (dp[x - 1, 0] == cnt[x - 1])
{
dp[x, 1] = dp[x - 1, 1];
dp[x, 2] = dp[x - 1, 1];
}
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])
{
dp[x, 2] = Math.Max(dp[x, 2],
dp[x - 1, 1]);
}
for (j = 0; j < 3; j++)
{
dp[x, j]++;
ans = Math.Max(ans, dp[x, j]);
}
}
return ans;
}
public static void Main()
{
int []arr = { 2, 6, 4, 8, 2, 9 };
int n = arr.Length;
Console.WriteLine(LongestSequence(arr, n));
}
}
|
Javascript
<script>
function LongestSequence(a, n)
{
var m = new Map();
var ar = Array(n+1).fill(0), i, j;
for (i = 1; i <= n; i++) {
ar[i] = a[i - 1];
}
a.sort((a,b)=>a-b);
var c = 1;
m.set(a[0], c);
for (i = 1; i <= n; i++) {
if (a[i] != a[i - 1]) {
c++;
m.set(a[i], c);
}
}
var cnt = new Map();
var dp = Array.from(Array(n+1), ()=>Array(3).fill(0));
cnt.set(0, 0);
for (i = 1; i <= n; i++) {
ar[i] = m.get(ar[i]);
if (cnt.has(ar[i]))
cnt.set(ar[i], cnt.get(ar[i])+1)
else
cnt.set(ar[i], 1)
}
var ans = 0, x;
for (i = 1; i <= n; i++) {
x = ar[i];
if (dp[x][0] == 0) {
if (dp[x - 1][0] == cnt.get(x - 1)) {
dp[x][1] = dp[x - 1][1];
dp[x][2] = dp[x - 1][1];
}
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]) {
dp[x][2] = Math.max(dp[x][2],
dp[x - 1][1]);
}
for (j = 0; j < 3; j++) {
dp[x][j]++;
ans = Math.max(ans, dp[x][j]);
}
}
return ans;
}
var arr = [2, 6, 4, 8, 2, 9];
var N = arr.length;
document.write( LongestSequence(arr, N));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...