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!