Open In App

Longest subarray of an array which is a subsequence in another array

Last Updated : 24 Nov, 2023
Suggest changes
Share
Like Article
Like
Report

Given two arrays arr1[] and arr2[], the task is to find the longest subarray of arr1[] which is a subsequence of arr2[].

Examples:

Input: arr1[] = {4, 2, 3, 1, 5, 6}, arr2[] = {3, 1, 4, 6, 5, 2}
Output: 3
Explanation: The longest subarray of arr1[] which is a subsequence in arr2[] is {3, 1, 5}

Input: arr1[] = {3, 2, 4, 7, 1, 5, 6, 8, 10, 9}, arr2[] = {9, 2, 4, 3, 1, 5, 6, 8, 10, 7}
Output: 5
Explanation: The longest subarray in arr1[] which is a subsequence in arr2[] is {1, 5, 6, 8, 10}.

Approach: The idea is to use Dynamic Programming to solve this problem. Follow the steps below to solve the problem:

  • Initialize a DP[][] table, where DP[i][j] stores the length of the longest subarray up to the ith index in arr1[] which is a subsequence in arr2[] up to the jth index.
  • Now, traverse over both the arrays and perform the following:
    • Case 1: If arr1[i] and arr2[j] are equal, add 1 to DP[i - 1][j - 1] as arr1[i] and arr2[j] contribute to the required length of the longest subarray.
    • Case 2: If arr1[i] and arr2[j] are not equal, set DP[i][j] = DP[i - 1][j].
  • Finally, print the maximum value present in DP[][] table as the required answer.

Below is the implementation of the above approach:

C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;  // Function to find the length of the  // longest subarray in arr1[] which  // is a subsequence in arr2[]  int LongSubarrSeq(int arr1[], int arr2[], int M, int N)  {  // Length of the array arr1[]  // Length of the required  // longest subarray  int maxL = 0;  // Initialize DP[]array  int DP[M + 1][N + 1];  // Traverse array arr1[]  for (int i = 1; i <= M; i++)  {  // Traverse array arr2[]  for (int j = 1; j <= N; j++)  {  if (arr1[i - 1] == arr2[j - 1])  {  // arr1[i - 1] contributes to  // the length of the subarray  DP[i][j] = 1 + DP[i - 1][j - 1];  }  // Otherwise  else   {  DP[i][j] = DP[i][j - 1];  }  }  }  // Find the maximum value  // present in DP[][]  for (int i = 1; i <= M; i++)   {  for (int j = 1; j <= N; j++)  {  maxL = max(maxL, DP[i][j]);  }  }  // Return the result  return maxL;  } // Driver Code int main() {  int arr1[] = { 4, 2, 3, 1, 5, 6 };  int M = sizeof(arr1) / sizeof(arr1[0]);    int arr2[] = { 3, 1, 4, 6, 5, 2 };  int N = sizeof(arr2) / sizeof(arr2[0]);  // Function call to find the length  // of the longest required subarray  cout << LongSubarrSeq(arr1, arr2, M, N) <<endl;  return 0; } // This code is contributed by code_hunt. 
Java
// Java program // for the above approach import java.io.*; class GFG {  // Function to find the length of the  // longest subarray in arr1[] which  // is a subsequence in arr2[]  private static int LongSubarrSeq(  int[] arr1, int[] arr2)  {  // Length of the array arr1[]  int M = arr1.length;  // Length of the array arr2[]  int N = arr2.length;  // Length of the required  // longest subarray  int maxL = 0;  // Initialize DP[]array  int[][] DP = new int[M + 1][N + 1];  // Traverse array arr1[]  for (int i = 1; i <= M; i++) {  // Traverse array arr2[]  for (int j = 1; j <= N; j++) {  if (arr1[i - 1] == arr2[j - 1]) {  // arr1[i - 1] contributes to  // the length of the subarray  DP[i][j] = 1 + DP[i - 1][j - 1];  }  // Otherwise  else {  DP[i][j] = DP[i][j - 1];  }  }  }  // Find the maximum value  // present in DP[][]  for (int i = 1; i <= M; i++) {  for (int j = 1; j <= N; j++) {  maxL = Math.max(maxL, DP[i][j]);  }  }  // Return the result  return maxL;  }  // Driver Code  public static void main(String[] args)  {  int[] arr1 = { 4, 2, 3, 1, 5, 6 };  int[] arr2 = { 3, 1, 4, 6, 5, 2 };  // Function call to find the length  // of the longest required subarray  System.out.println(LongSubarrSeq(arr1, arr2));  } } 
Python3
# Python program # for the above approach # Function to find the length of the # longest subarray in arr1 which # is a subsequence in arr2 def LongSubarrSeq(arr1, arr2): # Length of the array arr1 M = len(arr1); # Length of the array arr2 N = len(arr2); # Length of the required # longest subarray maxL = 0; # Initialize DParray DP = [[0 for i in range(N + 1)] for j in range(M + 1)]; # Traverse array arr1 for i in range(1, M + 1): # Traverse array arr2 for j in range(1, N + 1): if (arr1[i - 1] == arr2[j - 1]): # arr1[i - 1] contributes to # the length of the subarray DP[i][j] = 1 + DP[i - 1][j - 1]; # Otherwise else: DP[i][j] = DP[i][j - 1]; # Find the maximum value # present in DP for i in range(M + 1): # Traverse array arr2 for j in range(1, N + 1): maxL = max(maxL, DP[i][j]); # Return the result return maxL; # Driver Code if __name__ == '__main__': arr1 = [4, 2, 3, 1, 5, 6]; arr2 = [3, 1, 4, 6, 5, 2]; # Function call to find the length # of the longest required subarray print(LongSubarrSeq(arr1, arr2)); # This code contributed by shikhasingrajput  
C#
// C# program for the above approach using System; class GFG{ // Function to find the length of the // longest subarray in arr1[] which // is a subsequence in arr2[] private static int LongSubarrSeq(int[] arr1,   int[] arr2) {    // Length of the array arr1[]  int M = arr1.Length;    // Length of the array arr2[]  int N = arr2.Length;    // Length of the required  // longest subarray  int maxL = 0;    // Initialize DP[]array  int[,] DP = new int[M + 1, N + 1];  // Traverse array arr1[]  for(int i = 1; i <= M; i++)   {    // Traverse array arr2[]  for(int j = 1; j <= N; j++)   {  if (arr1[i - 1] == arr2[j - 1])  {    // arr1[i - 1] contributes to  // the length of the subarray  DP[i, j] = 1 + DP[i - 1, j - 1];  }  // Otherwise  else   {  DP[i, j] = DP[i, j - 1];  }  }  }  // Find the maximum value  // present in DP[][]  for(int i = 1; i <= M; i++)   {  for(int j = 1; j <= N; j++)   {  maxL = Math.Max(maxL, DP[i, j]);  }  }    // Return the result  return maxL; } // Driver Code static public void Main() {  int[] arr1 = { 4, 2, 3, 1, 5, 6 };  int[] arr2 = { 3, 1, 4, 6, 5, 2 };    // Function call to find the length  // of the longest required subarray  Console.WriteLine(LongSubarrSeq(arr1, arr2)); } } // This code is contributed by susmitakundugoaldanga 
JavaScript
<script> // javascript program of the above approach  // Function to find the length of the  // longest subarray in arr1[] which  // is a subsequence in arr2[]  function LongSubarrSeq(  arr1, arr2)  {  // Length of the array arr1[]  let M = arr1.length;  // Length of the array arr2[]  let N = arr2.length;  // Length of the required  // longest subarray  let maxL = 0;  // Initialize DP[]array  let DP = new Array(M + 1);    // Loop to create 2D array using 1D array  for (var i = 0; i < DP.length; i++) {  DP[i] = new Array(2);  }    for (var i = 0; i < DP.length; i++) {  for (var j = 0; j < DP.length; j++) {  DP[i][j] = 0;  }  }  // Traverse array arr1[]  for (let i = 1; i <= M; i++) {  // Traverse array arr2[]  for (let j = 1; j <= N; j++) {  if (arr1[i - 1] == arr2[j - 1]) {  // arr1[i - 1] contributes to  // the length of the subarray  DP[i][j] = 1 + DP[i - 1][j - 1];  }  // Otherwise  else {  DP[i][j] = DP[i][j - 1];  }  }  }  // Find the maximum value  // present in DP[][]  for (let i = 1; i <= M; i++) {  for (let j = 1; j <= N; j++) {  maxL = Math.max(maxL, DP[i][j]);  }  }  // Return the result  return maxL;  }  // Driver Code    let arr1 = [ 4, 2, 3, 1, 5, 6 ];  let arr2 = [ 3, 1, 4, 6, 5, 2 ];  // Function call to find the length  // of the longest required subarray  document.write(LongSubarrSeq(arr1, arr2)); </script> 

Output
3

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

Efficient Approach: Space optimization: In the previous approach the current value dp[i][j] only depends upon the current and previous row values of DP. So to optimize the space complexity we use a single 1D array to store the computations.

Implementation steps:

  • Create a 1D vector dp of size n+1.
  • Initialize a variable maxi to store the final answer and update it by iterating through the Dp.
  • Set a base case by initializing the values of DP.
  • Now iterate over subproblems with the help of a nested loop and get the current value from previous computations.
  • Now Create variables prev, temp used to store the previous values from previous computations.
  • After every iteration assign the value of temp to temp for further iteration.
  • At last return and print the final answer stored in maxi.

Implementation: 

C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; // Function to find the length of the // longest subarray in arr1[] // which is a subsequence in arr2[] int LongSubarrSeq(int arr1[], int arr2[], int M, int N) {  // to store final result  int maxL = 0;  // to store previous computations  // Initialize DP[] vector  vector<int> DP(N + 1, 0);  // iterate over subproblems to get the  // current value from previous computations  for (int i = 1; i <= M; i++) {  int prev = 0;  for (int j = 1; j <= N; j++) {  // Store current DP[j] value  int temp = DP[j];  if (arr1[i - 1] == arr2[j - 1]) {  DP[j] = 1 + prev;  maxL = max(maxL, DP[j]);  }  else {  DP[j] = DP[j - 1];  }  // Update previous DP[j] value  prev = temp;  }  }  // Return final answer  return maxL; } // Driver Code int main() {  int arr1[] = { 4, 2, 3, 1, 5, 6 };  int M = sizeof(arr1) / sizeof(arr1[0]);  int arr2[] = { 3, 1, 4, 6, 5, 2 };  int N = sizeof(arr2) / sizeof(arr2[0]);  cout << LongSubarrSeq(arr1, arr2, M, N);  return 0; } 
Java
// Java program for the above approach import java.util.*; public class Main {  // Function to find the length of the // longest subarray in arr1[] // which is a subsequence in arr2[] static int LongSubarrSeq(int arr1[], int arr2[], int M, int N) {  // to store final result  int maxL = 0;  // to store previous computations  // Initialize DP[] vector  int DP[] = new int[N + 1];  Arrays.fill(DP, 0);  // iterate over subproblems to get the  // current value from previous computations  for (int i = 1; i <= M; i++) {  int prev = 0;  for (int j = 1; j <= N; j++) {  // Store current DP[j] value  int temp = DP[j];  if (arr1[i - 1] == arr2[j - 1]) {  DP[j] = 1 + prev;  maxL = Math.max(maxL, DP[j]);  }  else {  DP[j] = DP[j - 1];  }  // Update previous DP[j] value  prev = temp;  }  }  // Return final answer  return maxL; } // Driver Code public static void main(String[] args) {  int arr1[] = { 4, 2, 3, 1, 5, 6 };  int M = arr1.length;  int arr2[] = { 3, 1, 4, 6, 5, 2 };  int N = arr2.length;  System.out.print(LongSubarrSeq(arr1, arr2, M, N)); } } 
Python3
# Function to find the length of the # longest subarray in arr1[] # which is a subsequence in arr2[] def LongSubarrSeq(arr1, arr2, M, N): # To store the final result maxL = 0 # To store previous computations # Initialize DP[] list DP = [0] * (N + 1) # Iterate over subproblems to get the # current value from previous computations for i in range(1, M + 1): prev = 0 for j in range(1, N + 1): # Store current DP[j] value temp = DP[j] if arr1[i - 1] == arr2[j - 1]: DP[j] = 1 + prev maxL = max(maxL, DP[j]) else: DP[j] = DP[j - 1] # Update previous DP[j] value prev = temp # Return the final answer return maxL # Driver Code if __name__ == "__main__": arr1 = [4, 2, 3, 1, 5, 6] M = len(arr1) arr2 = [3, 1, 4, 6, 5, 2] N = len(arr2) print(LongSubarrSeq(arr1, arr2, M, N)) 
C#
using System; class Program {  // Function to find the length of the  // longest subarray in arr1[]  // which is a subsequence in arr2[]  static int LongSubarrSeq(int[] arr1, int[] arr2, int M, int N)  {  // to store final result  int maxL = 0;  // to store previous computations  // Initialize DP[] array  int[] DP = new int[N + 1];  // iterate over subproblems to get the  // current value from previous computations  for (int i = 1; i <= M; i++)  {  int prev = 0;  for (int j = 1; j <= N; j++)  {  // Store current DP[j] value  int temp = DP[j];  if (arr1[i - 1] == arr2[j - 1])  {  DP[j] = 1 + prev;  maxL = Math.Max(maxL, DP[j]);  }  else  {  DP[j] = DP[j - 1];  }  // Update previous DP[j] value  prev = temp;  }  }  // Return final answer  return maxL;  }  // Driver Code  static void Main()  {  int[] arr1 = { 4, 2, 3, 1, 5, 6 };  int M = arr1.Length;  int[] arr2 = { 3, 1, 4, 6, 5, 2 };  int N = arr2.Length;  Console.WriteLine(LongSubarrSeq(arr1, arr2, M, N));  } } 
JavaScript
// Function to find the length of the // longest subarray in arr1[] // which is a subsequence in arr2[] function LongSubarrSeq(arr1, arr2, M, N) {  // to store final result  let maxL = 0;  // to store previous computations  // Initialize DP[] array  let DP = new Array(N + 1).fill(0);  // iterate over subproblems to get the  // current value from previous computations  for (let i = 1; i <= M; i++) {  let prev = 0;  for (let j = 1; j <= N; j++) {  // Store current DP[j] value  let temp = DP[j];  if (arr1[i - 1] === arr2[j - 1]) {  DP[j] = 1 + prev;  maxL = Math.max(maxL, DP[j]);  } else {  DP[j] = DP[j - 1];  }  // Update previous DP[j] value  prev = temp;  }  }  // Return final answer  return maxL; } // Driver Code let arr1 = [4, 2, 3, 1, 5, 6]; let M = arr1.length; let arr2 = [3, 1, 4, 6, 5, 2]; let N = arr2.length; console.log(LongSubarrSeq(arr1, arr2, M, N)); 

Output
3

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

Related Topic: Subarrays, Subsequences, and Subsets in Array


Next Article

Similar Reads