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> |
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)) |
3
Time Complexity: O(M * N)
Auxiliary Space: O(N)
Related Topic: Subarrays, Subsequences, and Subsets in Array
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!