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

• Difficulty Level : Medium
• Last Updated : 13 May, 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;``int` `KMPArray;` `// 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 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``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 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 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 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`

## Javascript

 ``

Output:

`3`

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

My Personal Notes arrow_drop_up