Open in App
Not now

# Length of the longest increasing subsequence which does not contain a given sequence as Subarray

• Difficulty Level : Medium
• Last Updated : 11 Jul, 2022

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: 4
Explanation: Required longest increasing subsequence is {3, 3, 4, 7}.

Input: arr[] = {1, 2, 3}, arr1[] = {1, 2, 3}
Output: 2
Explanation: Required longest increasing subsequence is {1, 2}.

Naive Approach: The simplest approach is to generate all possible subsequences of the given array and print the length of the longest subsequence among them, which does not contain arr1[] as subarray.

Time Complexity: O(M * 2N) where N and M are the lengths of the given arrays.
Auxiliary Space: O(M + N)

Efficient Approach: The idea is to use lps[] array generated using KMP Algorithm and Dynamic Programming to find the longest non-decreasing subsequence without any subarray equals to sequence[]. Follow the below steps to solve the problem:

1. Initialize an array dp[N][N][N] where dp[i][j][K] stores the maximum length of non-decreasing subsequence up to index i where j is the index of the previously chosen element in the array arr[] and K denotes that the currently found sequence contains subarray sequence[0, K].
2. Also, generate an array to store the length of the longest prefix suffix using KMP Algorithm.
3. The maximum length can be found by memoizing the below dp transitions:

dp(i, prev, k) = max(1 + dp(i + 1, i, k2), dp(i + 1, prev, k)) where,

• i is the current index.
• prev is the previously chosen element.
• k2 is index of prefix subarray included so far in the currently found sequence which can be found using KMP Array for longest prefix suffix.

Base Case:

• If k is equals to the length of the given sequence, return as the currently found subsequence contains the arr1[].
• If i reaches N, return as no more elements exist.
• If the current state has already been calculated, return.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach ` `#include ` `using` `namespace` `std; ` ` `  `// Initialize dp and KMP array ` `int` `dp[6][6][6]; ` `int` `KMPArray[2]; ` ` `  `// Length of the given sequence[] ` `int` `m; ` ` `  `// Function to find the max-length ` `// subsequence that does not have ` `// subarray sequence[] ` `int` `findSubsequence(``int` `a[], ``int` `sequence[], ``int` `i,  ` `                    ``int` `prev, ``int` `k, ``int` `al, ``int` `sl) ` `{ ` `    ``// Stores the subsequence ` `    ``// explored so far ` `    ``if` `(k == m) ` `        ``return` `INT_MIN; ` ` `  `    ``// Base Case ` `    ``if` `(i == al) ` `        ``return` `0; ` ` `  `    ``// Using memoization to ` `    ``// avoid re-computation ` `    ``if` `(prev != -1 && dp[i][prev][k] != -1) { ` `        ``return` `dp[i][prev][k]; ` `    ``} ` ` `  `    ``int` `include = 0; ` ` `  `    ``if` `(prev == -1 || a[i] >= a[prev]) { ` `        ``int` `k2 = k; ` ` `  `        ``// Using KMP array to find ` `        ``// corresponding index in arr1[] ` `        ``while` `(k2 > 0 ` `               ``&& a[i] != sequence[k2]) ` `            ``k2 = KMPArray[k2 - 1]; ` ` `  `        ``// Incrementing k2 as we are ` `        ``// including this element in ` `        ``// the subsequence ` `        ``if` `(a[i] == sequence[k2]) ` `            ``k2++; ` ` `  `        ``// Possible answer for ` `        ``// current state ` `        ``include = 1 ` `                  ``+ findSubsequence( ` `                        ``a, sequence, ` `                        ``i + 1, i, k2, al, sl); ` `    ``} ` ` `  `    ``// Maximum answer for ` `    ``// current state ` `    ``int` `ans = max( ` `        ``include, findSubsequence( ` `                     ``a, sequence, ` `                     ``i + 1, prev, k, al, sl)); ` ` `  `    ``// Memoizing the answer for ` `    ``// the corresponding state ` `    ``if` `(prev != -1) { ` `        ``dp[i][prev][k] = ans; ` `    ``} ` ` `  `    ``// Return the answer for ` `    ``// current state ` `    ``return` `ans; ` `} ` ` `  `// Function that generate KMP Array ` `void` `fillKMPArray(``int` `pattern[]) ` `{ ` `   `  `    ``// Previous longest prefix suffix ` `    ``int` `j = 0; ` ` `  `    ``int` `i = 1; ` ` `  `    ``// KMPArray[0] is a always 0 ` `    ``KMPArray[0] = 0; ` ` `  `    ``// The loop calculates KMPArray[i] ` `    ``// for i = 1 to M - 1 ` `    ``while` `(i < m) { ` ` `  `        ``// If current character is ` `        ``// same ` `        ``if` `(pattern[i] == pattern[j]) { ` `            ``j++; ` ` `  `            ``// Update the KMP array ` `            ``KMPArray[i] = j; ` `            ``i++; ` `        ``} ` ` `  `        ``// Otherwise ` `        ``else` `{ ` ` `  `            ``// Update the KMP array ` `            ``if` `(j != 0) ` `                ``j = KMPArray[j - 1]; ` `            ``else` `{ ` `                ``KMPArray[i] = j; ` `                ``i++; ` `            ``} ` `        ``} ` `    ``} ` `} ` ` `  `// Function to print the maximum ` `// possible length ` `void` `printAnswer(``int` `a[], ``int` `sequence[], ``int` `al, ``int` `sl) ` `{ ` ` `  `    ``// Length of the given sequence ` `    ``m = sl; ` ` `  `    ``// Generate KMP array ` `    ``fillKMPArray(sequence); ` ` `  `     `  ` `  `    ``// Initialize the states to -1 ` `    ``memset``(dp, -1, ``sizeof``(dp)); ` ` `  `    ``// Get answer ` `    ``int` `ans = findSubsequence(a, sequence, 0, -1, 0, al, sl); ` ` `  `    ``// Print answer ` `    ``cout << ((ans < 0) ? 0 : ans) << endl; ` `} ` `     `  `// Driver code ` `int` `main() ` `{ ` `   `  `    ``// Given array ` `    ``int` `arr[] = { 5, 3, 9, 3, 4, 7 }; ` ` `  `    ``// Give arr1 ` `    ``int` `arr1[] = { 3, 4 }; ` ` `  `    ``// Function Call ` `    ``printAnswer(arr, arr1, 6, 2); ` `    ``return` `0; ` `} ` ` `  `// This code is contributed by divyeshrabadiya07.`

## Java

 `// Java program for the above approach ` ` `  `import` `java.io.*; ` `import` `java.util.*; ` ` `  `class` `GFG { ` ` `  `    ``// Initialize dp and KMP array ` `    ``static` `int``[][][] dp; ` `    ``static` `int``[] KMPArray; ` ` `  `    ``// Length of the given sequence[] ` `    ``static` `int` `m; ` ` `  `    ``// Function to find the max-length ` `    ``// subsequence that does not have ` `    ``// subarray sequence[] ` `    ``private` `static` `int` `findSubsequence( ` `        ``int``[] a, ``int``[] sequence, ` `        ``int` `i, ``int` `prev, ``int` `k) ` `    ``{ ` `        ``// Stores the subsequence ` `        ``// explored so far ` `        ``if` `(k == m) ` `            ``return` `Integer.MIN_VALUE; ` ` `  `        ``// Base Case ` `        ``if` `(i == a.length) ` `            ``return` `0``; ` ` `  `        ``// Using memoization to ` `        ``// avoid re-computation ` `        ``if` `(prev != -``1` `            ``&& dp[i][prev][k] != -``1``) { ` `            ``return` `dp[i][prev][k]; ` `        ``} ` ` `  `        ``int` `include = ``0``; ` ` `  `        ``if` `(prev == -``1` `|| a[i] >= a[prev]) { ` `            ``int` `k2 = k; ` ` `  `            ``// Using KMP array to find ` `            ``// corresponding index in arr1[] ` `            ``while` `(k2 > ``0` `                   ``&& a[i] != sequence[k2]) ` `                ``k2 = KMPArray[k2 - ``1``]; ` ` `  `            ``// Incrementing k2 as we are ` `            ``// including this element in ` `            ``// the subsequence ` `            ``if` `(a[i] == sequence[k2]) ` `                ``k2++; ` ` `  `            ``// Possible answer for ` `            ``// current state ` `            ``include = ``1` `                      ``+ findSubsequence( ` `                            ``a, sequence, ` `                            ``i + ``1``, i, k2); ` `        ``} ` ` `  `        ``// Maximum answer for ` `        ``// current state ` `        ``int` `ans = Math.max( ` `            ``include, findSubsequence( ` `                         ``a, sequence, ` `                         ``i + ``1``, prev, k)); ` ` `  `        ``// Memoizing the answer for ` `        ``// the corresponding state ` `        ``if` `(prev != -``1``) { ` `            ``dp[i][prev][k] = ans; ` `        ``} ` ` `  `        ``// Return the answer for ` `        ``// current state ` `        ``return` `ans; ` `    ``} ` ` `  `    ``// Function that generate KMP Array ` `    ``private` `static` `void` `    ``fillKMPArray(``int``[] pattern) ` `    ``{ ` `        ``// Previous longest prefix suffix ` `        ``int` `j = ``0``; ` ` `  `        ``int` `i = ``1``; ` ` `  `        ``// KMPArray[0] is a always 0 ` `        ``KMPArray[``0``] = ``0``; ` ` `  `        ``// The loop calculates KMPArray[i] ` `        ``// for i = 1 to M - 1 ` `        ``while` `(i < m) { ` ` `  `            ``// If current character is ` `            ``// same ` `            ``if` `(pattern[i] == pattern[j]) { ` `                ``j++; ` ` `  `                ``// Update the KMP array ` `                ``KMPArray[i] = j; ` `                ``i++; ` `            ``} ` ` `  `            ``// Otherwise ` `            ``else` `{ ` ` `  `                ``// Update the KMP array ` `                ``if` `(j != ``0``) ` `                    ``j = KMPArray[j - ``1``]; ` `                ``else` `{ ` `                    ``KMPArray[i] = j; ` `                    ``i++; ` `                ``} ` `            ``} ` `        ``} ` `    ``} ` ` `  `    ``// Function to print the maximum ` `    ``// possible length ` `    ``static` `void` `printAnswer( ` `        ``int` `a[], ``int` `sequence[]) ` `    ``{ ` ` `  `        ``// Length of the given sequence ` `        ``m = sequence.length; ` ` `  `        ``// Initialize kmp array ` `        ``KMPArray = ``new` `int``[m]; ` ` `  `        ``// Generate KMP array ` `        ``fillKMPArray(sequence); ` ` `  `        ``// Initialize dp ` `        ``dp = ``new` `int``[a.length][a.length][a.length]; ` ` `  `        ``// Initialize the states to -1 ` `        ``for` `(``int` `i = ``0``; i < a.length; i++) ` `            ``for` `(``int` `j = ``0``; j < a.length; j++) ` `                ``Arrays.fill(dp[i][j], -``1``); ` ` `  `        ``// Get answer ` `        ``int` `ans = findSubsequence( ` `            ``a, sequence, ``0``, -``1``, ``0``); ` ` `  `        ``// Print answer ` `        ``System.out.println((ans < ``0``) ? ``0` `: ans); ` `    ``} ` ` `  `    ``// Driver code ` `    ``public` `static` `void` `        ``main(String[] args) ``throws` `Exception ` `    ``{ ` `        ``// Given array ` `        ``int``[] arr = { ``5``, ``3``, ``9``, ``3``, ``4``, ``7` `}; ` ` `  `        ``// Give arr1 ` `        ``int``[] arr1 = { ``3``, ``4` `}; ` ` `  `        ``// Function Call ` `        ``printAnswer(arr, arr1); ` `    ``} ` `} `

## Python3

 `# Python program for the above approach ` ` `  `# Initialize dp and KMP array ` `from` `pickle ``import` `GLOBAL ` `import` `sys ` ` `  `dp ``=` `[[[``-``1` `for` `i ``in` `range``(``6``)]``for` `j ``in` `range``(``6``)]``for` `k ``in` `range``(``6``)] ` `KMPArray ``=` `[``0` `for` `i ``in` `range``(``2``)] ` ` `  `# Length of the given sequence[] ` `m ``=` `0` ` `  `# Function to find the max-length ` `# subsequence that does not have ` `# subarray sequence[] ` `def` `findSubsequence(a, sequence, i,prev, k, al, sl): ` `    ``global` `KMPArray ` `    ``global` `dp ` `     `  `    ``# Stores the subsequence ` `    ``# explored so far ` `    ``if` `(k ``=``=` `m): ` `        ``return` `-``sys.maxsize ``-``1` ` `  `    ``# Base Case ` `    ``if` `(i ``=``=` `al): ` `        ``return` `0` ` `  `    ``# Using memoization to ` `    ``# avoid re-computation ` `    ``if` `(prev !``=` `-``1` `and` `dp[i][prev][k] !``=` `-``1``): ` `        ``return` `dp[i][prev][k] ` ` `  `    ``include ``=` `0` ` `  `    ``if` `(prev ``=``=` `-``1` `or` `a[i] >``=` `a[prev]): ` `        ``k2 ``=` `k ` ` `  `        ``# Using KMP array to find ` `        ``# corresponding index in arr1[] ` `        ``while` `(k2 > ``0` `            ``and` `a[i] !``=` `sequence[k2]): ` `            ``k2 ``=` `KMPArray[k2 ``-` `1``] ` ` `  `        ``# Incrementing k2 as we are ` `        ``# including this element in ` `        ``# the subsequence ` `        ``if` `(a[i] ``=``=` `sequence[k2]): ` `            ``k2 ``+``=` `1` ` `  `        ``# Possible answer for ` `        ``# current state ` `        ``include ``=` `1` `+` `findSubsequence( ` `                        ``a, sequence, ` `                        ``i ``+` `1``, i, k2, al, sl) ` ` `  `    ``# Maximum answer for ` `    ``# current state ` `    ``ans ``=` `max``(include, findSubsequence( ` `                    ``a, sequence, ` `                    ``i ``+` `1``, prev, k, al, sl)) ` ` `  `    ``# Memoizing the answer for ` `    ``# the corresponding state ` `    ``if` `(prev !``=` `-``1``) : ` `        ``dp[i][prev][k] ``=` `ans ` ` `  `    ``# Return the answer for ` `    ``# current state ` `    ``return` `ans ` ` `  `# Function that generate KMP Array ` `def` `fillKMPArray(pattern): ` `    ``global` `m ` `    ``global` `KMPArray ` ` `  `    ``# Previous longest prefix suffix ` `    ``j ``=` `0` ` `  `    ``i ``=` `1` ` `  `    ``# KMPArray[0] is a always 0 ` `    ``KMPArray[``0``] ``=` `0` ` `  `    ``# The loop calculates KMPArray[i] ` `    ``# for i = 1 to M - 1 ` `    ``while` `(i < m): ` ` `  `        ``# If current character is ` `        ``# same ` `        ``if` `(pattern[i] ``=``=` `pattern[j]): ` `            ``j ``+``=` `1` ` `  `            ``# Update the KMP array ` `            ``KMPArray[i] ``=` `j ` `            ``i ``+``=` `1` ` `  `        ``# Otherwise ` `        ``else``: ` ` `  `            ``# Update the KMP array ` `            ``if` `(j !``=` `0``): ` `                ``j ``=` `KMPArray[j ``-` `1``] ` `            ``else``: ` `                ``KMPArray[i] ``=` `j ` `                ``i ``+``=` `1` ` `  `# Function to print the maximum ` `# possible length ` `def` `printAnswer(a, sequence, al, sl): ` ` `  `    ``global` `m ` ` `  `    ``# Length of the given sequence ` `    ``m ``=` `sl ` ` `  `    ``# Generate KMP array ` `    ``fillKMPArray(sequence) ` ` `  `    ``# Get answer ` `    ``ans ``=` `findSubsequence(a, sequence, ``0``, ``-``1``, ``0``, al, sl) ` ` `  `    ``# Print answer ` `    ``if``(ans < ``0``): ` `        ``print``(``0``) ` `    ``else` `: ` `        ``print``(ans) ` ` `  `     `  `# Driver code ` ` `  `# Given array ` `arr ``=` `[ ``5``, ``3``, ``9``, ``3``, ``4``, ``7` `] ` ` `  `# Give arr1 ` `arr1 ``=` `[ ``3``, ``4` `] ` ` `  `# Function Call ` `printAnswer(arr, arr1, ``6``, ``2``) ` ` `  `# This code is contributed by shinjanpatra`

## C#

 `// C# program for the above approach ` `using` `System; ` `using` `System.Collections; ` `using` `System.Collections.Generic; ` ` `  `class` `GFG{ ` ` `  `// Initialize dp and KMP array ` `static` `int``[,,] dp; ` `static` `int``[] KMPArray; ` ` `  `// Length of the given sequence[] ` `static` `int` `m; ` ` `  `// Function to find the max-length ` `// subsequence that does not have ` `// subarray sequence[] ` `private` `static` `int` `findSubsequence(``int``[] a, ` `                                   ``int``[] sequence, ` `                                   ``int` `i, ``int` `prev, ` `                                   ``int` `k) ` `{ ` `     `  `    ``// Stores the subsequence ` `    ``// explored so far ` `    ``if` `(k == m) ` `        ``return` `int``.MinValue; ` ` `  `    ``// Base Case ` `    ``if` `(i == a.Length) ` `        ``return` `0; ` ` `  `    ``// Using memoization to ` `    ``// avoid re-computation ` `    ``if` `(prev != -1 && dp[i, prev, k] != -1)  ` `    ``{ ` `        ``return` `dp[i, prev, k]; ` `    ``} ` ` `  `    ``int` `include = 0; ` ` `  `    ``if` `(prev == -1 || a[i] >= a[prev]) ` `    ``{ ` `        ``int` `k2 = k; ` ` `  `        ``// Using KMP array to find ` `        ``// corresponding index in arr1[] ` `        ``while` `(k2 > 0 && a[i] != sequence[k2]) ` `            ``k2 = KMPArray[k2 - 1]; ` ` `  `        ``// Incrementing k2 as we are ` `        ``// including this element in ` `        ``// the subsequence ` `        ``if` `(a[i] == sequence[k2]) ` `            ``k2++; ` ` `  `        ``// Possible answer for ` `        ``// current state ` `        ``include = 1 + findSubsequence(a, sequence, ` `                                      ``i + 1, i, k2); ` `    ``} ` ` `  `    ``// Maximum answer for ` `    ``// current state ` `    ``int` `ans = Math.Max(include, ` `                       ``findSubsequence(a, sequence,  ` `                                       ``i + 1, prev, k)); ` ` `  `    ``// Memoizing the answer for ` `    ``// the corresponding state ` `    ``if` `(prev != -1) ` `    ``{ ` `        ``dp[i, prev, k] = ans; ` `    ``} ` ` `  `    ``// Return the answer for ` `    ``// current state ` `    ``return` `ans; ` `} ` ` `  `// Function that generate KMP Array ` `private` `static` `void` `fillKMPArray(``int``[] pattern) ` `{ ` `     `  `    ``// Previous longest prefix suffix ` `    ``int` `j = 0; ` ` `  `    ``int` `i = 1; ` ` `  `    ``// KMPArray[0] is a always 0 ` `    ``KMPArray[0] = 0; ` ` `  `    ``// The loop calculates KMPArray[i] ` `    ``// for i = 1 to M - 1 ` `    ``while` `(i < m) ` `    ``{ ` `         `  `        ``// If current character is ` `        ``// same ` `        ``if` `(pattern[i] == pattern[j]) ` `        ``{ ` `            ``j++; ` ` `  `            ``// Update the KMP array ` `            ``KMPArray[i] = j; ` `            ``i++; ` `        ``} ` ` `  `        ``// Otherwise ` `        ``else`  `        ``{ ` `             `  `            ``// Update the KMP array ` `            ``if` `(j != 0) ` `                ``j = KMPArray[j - 1]; ` `            ``else`  `            ``{ ` `                ``KMPArray[i] = j; ` `                ``i++; ` `            ``} ` `        ``} ` `    ``} ` `} ` ` `  `// Function to print the maximum ` `// possible length ` `static` `void` `printAnswer(``int``[] a, ``int``[] sequence) ` `{ ` `     `  `    ``// Length of the given sequence ` `    ``m = sequence.Length; ` ` `  `    ``// Initialize kmp array ` `    ``KMPArray = ``new` `int``[m]; ` ` `  `    ``// Generate KMP array ` `    ``fillKMPArray(sequence); ` ` `  `    ``// Initialize dp ` `    ``dp = ``new` `int``[a.Length, a.Length, a.Length]; ` ` `  `    ``// Initialize the states to -1 ` `    ``for``(``int` `i = 0; i < a.Length; i++) ` `        ``for``(``int` `j = 0; j < a.Length; j++) ` `            ``for``(``int` `k = 0; k < a.Length; k++) ` `                ``dp[i, j, k] = -1; ` ` `  `    ``// Get answer ` `    ``int` `ans = findSubsequence(a, sequence, 0, -1, 0); ` ` `  `    ``// Print answer ` `    ``Console.WriteLine((ans < 0) ? 0 : ans); ` `} ` ` `  `// Driver code ` `public` `static` `void` `Main() ` `{ ` `     `  `    ``// Given array ` `    ``int``[] arr = { 5, 3, 9, 3, 4, 7 }; ` ` `  `    ``// Give arr1 ` `    ``int``[] arr1 = { 3, 4 }; ` ` `  `    ``// Function Call ` `    ``printAnswer(arr, arr1); ` `} ` `} ` ` `  `// This code is contributed by akhilsaini`

## Javascript

 ``

Output:

`3`

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

Related Topic: Subarrays, Subsequences, and Subsets in Array

My Personal Notes arrow_drop_up
Related Articles