Given two arrays firstArr[], consisting of distinct elements only, and secondArr[], the task is to find the length of LCS between these 2 arrays.
Examples:
Input: firstArr[] = {3, 5, 1, 8}, secondArr[] = {3, 3, 5, 3, 8}
Output: 3.
Explanation: LCS between these two arrays is {3, 5, 8}.Input : firstArr[] = {1, 2, 1}, secondArr[] = {3}
Output: 0
Naive Approach: Follow the steps below to solve the problem using the simplest possible approach:
- Initialize an array dp[][] such that dp[i][j] stores longest common subsequence of firstArr[ :i] and secondArr[ :j].
- Traverse the array firstArr[] and for every array element of the array firstArr[], traverse the array secondArr[].
- If firstArr[i] = secondArr[j]: Set dp[i][j] = dp[i – 1][j – 1] + 1.
- Otherwise: Set dp[i][j] = max(dp[ i – 1][j], dp[i][j – 1]).
Time Complexity: O(N * M), where N and M are the sizes of the arrays firstArr[] and secondArr[] respectively.Â
Auxiliary Space: O(N * M)
Efficient Approach: To optimize the above approach, follow the steps below:Â
- Initialize a Map, say mp, to store the mappings map[firstArr[i]] = i, i.e. map elements of the first array to their respective indices.
- Since the elements which are present in secondArr[] but not in the firstArr[] are not useful at all, as they can never be a part of a common subsequence, traverse the array secondArr[] andfor each array element, check if it is present in the Map or not.
- If found to be true, push map[secondArr[i]] into a temporary Array. Otherwise ignore it.
- Find the Longest Increasing Subsequence (LIS) of the obtained temporary array and print its length as the required answer.
Illustration:Â
firstArr[] = {3, 5, 1, 8}Â
secondArr={3, 3, 4, 5, 3, 8}Â
Mapping: 3->0, 5->1, 1->2, 8->3 (From firstArr)Â
tempArr[] = {0, 0, 1, 0, 3}Â
Therefore, length of LIS of tempArr[] = 3 ({0, 1, 3})Â
Below is the implementation of the above approach:Â
C++
// C++ program to implement // the above approach Â
#include <bits/stdc++.h> using namespace std; Â
// Function to find the Longest Common // Subsequence between the two arrays int LCS(vector< int >& firstArr, Â Â Â Â Â Â Â Â vector< int >& secondArr) { Â
    // Maps elements of firstArr[]     // to their respective indices     unordered_map< int , int > mp; Â
    // Traverse the array firstArr[]     for ( int i = 0; i < firstArr.size(); i++) {         mp[firstArr[i]] = i + 1;     } Â
    // Stores the indices of common elements     // between firstArr[] and secondArr[]     vector< int > tempArr; Â
    // Traverse the array secondArr[]     for ( int i = 0; i < secondArr.size(); i++) { Â
        // If current element exists in the Map         if (mp.find(secondArr[i]) != mp.end()) { Â
            tempArr.push_back(mp[secondArr[i]]);         }     } Â
    // Stores lIS from tempArr[]     vector< int > tail; Â
    tail.push_back(tempArr[0]); Â
    for ( int i = 1; i < tempArr.size(); i++) { Â
        if (tempArr[i] > tail.back())             tail.push_back(tempArr[i]); Â
        else if (tempArr[i] < tail[0])             tail[0] = tempArr[i]; Â
        else {             auto it = lower_bound(tail.begin(),                                   tail.end(),                                   tempArr[i]);             *it = tempArr[i];         }     }     return ( int )tail.size(); } Â
// Driver Code int main() { Â Â Â Â vector< int > firstArr = { 3, 5, 1, 8 }; Â Â Â Â vector< int > secondArr = { 3, 3, 5, 3, 8 }; Â Â Â Â cout << LCS(firstArr, secondArr); Â Â Â Â return 0; } |
Java
// Java program to implement // the above approach import java.util.*; class GFG { Â
// Function to find the Longest Common // Subsequence between the two arrays static int LCS( int [] firstArr, int [] secondArr) { Â
    // Maps elements of firstArr[]     // to their respective indices     HashMap<Integer,Integer> mp = new HashMap<Integer,Integer>(); Â
    // Traverse the array firstArr[]     for ( int i = 0 ; i < firstArr.length; i++)     {         mp.put(firstArr[i], i + 1 );     } Â
    // Stores the indices of common elements     // between firstArr[] and secondArr[]     Vector<Integer> tempArr = new Vector<>(); Â
    // Traverse the array secondArr[]     for ( int i = 0 ; i < secondArr.length; i++)     { Â
        // If current element exists in the Map         if (mp.containsKey(secondArr[i]))         {             tempArr.add(mp.get(secondArr[i]));         }     } Â
    // Stores lIS from tempArr[]     Vector<Integer> tail = new Vector<>();     tail.add(tempArr.get( 0 )); Â
    for ( int i = 1 ; i < tempArr.size(); i++)     {         if (tempArr.get(i) > tail.lastElement())             tail.add(tempArr.get(i));         else if (tempArr.get(i) < tail.get( 0 ))             tail.add( 0 , tempArr.get(i));         }     return ( int )tail.size(); } Â
// Driver Code public static void main(String[] args) { Â Â Â Â int [] firstArr = { 3 , 5 , 1 , 8 }; Â Â Â Â int [] secondArr = { 3 , 3 , 5 , 3 , 8 }; Â Â Â Â System.out.print(LCS(firstArr, secondArr)); } } Â
// This code is contributed by gauravrajput1 |
Python3
# Python3 program to implement # the above approach from bisect import bisect_left Â
# Function to find the Longest Common # Subsequence between the two arrays def LCS(firstArr, secondArr): Â
    # Maps elements of firstArr[]     # to their respective indices     mp = {} Â
    # Traverse the array firstArr[]     for i in range ( len (firstArr)):         mp[firstArr[i]] = i + 1 Â
    # Stores the indices of common elements     # between firstArr[] and secondArr[]     tempArr = [] Â
    # Traverse the array secondArr[]     for i in range ( len (secondArr)): Â
        # If current element exists in the Map         if (secondArr[i] in  mp):             tempArr.append(mp[secondArr[i]]) Â
    # Stores lIS from tempArr[]     tail = []     tail.append(tempArr[ 0 ])     for i in range ( 1 , len (tempArr)):         if (tempArr[i] > tail[ - 1 ]):             tail.append(tempArr[i])         elif (tempArr[i] < tail[ 0 ]):             tail[ 0 ] = tempArr[i]         else :             it = bisect_left(tail, tempArr[i])             it = tempArr[i]     return len (tail) Â
# Driver Code if __name__ = = '__main__' : Â Â Â Â firstArr = [ 3 , 5 , 1 , 8 ] Â Â Â Â secondArr = [ 3 , 3 , 5 , 3 , 8 ] Â Â Â Â print (LCS(firstArr, secondArr)) Â
# This code is contributed by mohit kumar 29 |
C#
// C# program to implement // the above approach using System; using System.Collections.Generic; public class GFG { Â
// Function to find the longest Common // Subsequence between the two arrays static int LCS( int [] firstArr, int [] secondArr) { Â
    // Maps elements of firstArr[]     // to their respective indices     Dictionary< int , int > mp = new Dictionary< int , int >(); Â
    // Traverse the array firstArr[]     for ( int i = 0; i < firstArr.Length; i++)     {         mp.Add(firstArr[i], i + 1);     } Â
    // Stores the indices of common elements     // between firstArr[] and secondArr[]     List< int > tempArr = new List< int >(); Â
    // Traverse the array secondArr[]     for ( int i = 0; i < secondArr.Length; i++)     { Â
        // If current element exists in the Map         if (mp.ContainsKey(secondArr[i]))         {             tempArr.Add(mp[secondArr[i]]);         }     } Â
    // Stores lIS from tempArr[]     List< int > tail = new List< int >();     tail.Add(tempArr[0]); Â
    for ( int i = 1; i < tempArr.Count; i++)     {         if (tempArr[i] > tail[tail.Count-1])             tail.Add(tempArr[i]);         else if (tempArr[i] < tail[0])             tail.Insert(0, tempArr[i]);         }     return ( int )tail.Count; } Â
// Driver Code public static void Main(String[] args) { Â Â Â Â int [] firstArr = { 3, 5, 1, 8 }; Â Â Â Â int [] secondArr = { 3, 3, 5, 3, 8 }; Â Â Â Â Console.Write(LCS(firstArr, secondArr)); } } Â
// This code is contributed by Rajput-Ji. |
Javascript
<script> Â
// Javascript program to implement // the above approach Â
// Function to find the longest Common // Subsequence between the two arrays function LCS(firstArr, secondArr) {          // Maps elements of firstArr[]     // to their respective indices     let mp = new Map() Â
    // Traverse the array firstArr[]     for (let i = 0; i < firstArr.length; i++)     {         mp.set(firstArr[i], i + 1);     } Â
    // Stores the indices of common elements     // between firstArr[] and secondArr[]     let tempArr = []; Â
    // Traverse the array secondArr[]     for (let i = 0; i < secondArr.length; i++)     {                  // If current element exists in the Map         if (mp.has(secondArr[i]))         {             tempArr.push(mp.get(secondArr[i]));         }     } Â
    // Stores lIS from tempArr[]     let tail = [];     tail.push(tempArr[0]); Â
    for (let i = 1; i < tempArr.length; i++)     {         if (tempArr[i] > tail[tail.length - 1])             tail.push(tempArr[i]);                      else if (tempArr[i] < tail[0])             tail.unshift(0, tempArr[i]);       }     return tail.length; } Â
// Driver Code let firstArr = [ 3, 5, 1, 8 ]; let secondArr = [ 3, 3, 5, 3, 8 ]; Â
document.write(LCS(firstArr, secondArr)); Â
// This code is contributed by gfgking Â
</script> |
3
Â
Time Complexity: O(NlogN)
Auxiliary Space: O(N)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!