Related Articles
Length of the longest increasing subsequence which does not contain a given sequence as Subarray
• Last Updated : 06 Nov, 2020

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:

## 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 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);` `    ``}` `}`

## 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 is a always 0` `    ``KMPArray = 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`

Output:

```3

```

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

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.

My Personal Notes arrow_drop_up
Recommended Articles
Page :