Related Articles

Related Articles

Longest Common Subsequence of two arrays out of which one array consists of distinct elements only
  • Last Updated : 13 Jan, 2021

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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to 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;
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to 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

chevron_right


Output: 

3

 

Time Complexity: O(NlogN)
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up
Recommended Articles
Page :