Given two sequence P and Q of numbers. The task is to find Longest Common Subsequence of two sequences if we are allowed to change at most k element in first sequence to any value.
Examples:
Input : P = { 8, 3 }
Q = { 1, 3 }
K = 1
Output : 2
If we change first element of first
sequence from 8 to 1, both sequences
become same.
Input : P = { 1, 2, 3, 4, 5 }
Q = { 5, 3, 1, 4, 2 }
K = 1
Output : 3
By changing first element of first
sequence to 5 to get the LCS ( 5, 3, 4 }.
The idea is to use Dynamic Programming. Define a 3D matrix dp[][][], where dp[i][j][k] defines the Longest Common Subsequence for the first i numbers of first array, first j number of second array when we are allowed to change at max k number in the first array.
Therefore, recursion will look like
If P[i] != Q[j],
dp[i][j][k] = max(dp[i - 1][j][k],
dp[i][j - 1][k],
dp[i - 1][j - 1][k - 1] + 1)
If P[i] == Q[j],
dp[i][j][k] = max(dp[i - 1][j][k],
dp[i][j - 1][k],
dp[i - 1][j - 1][k] + 1)
Below is the implementation of this approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define MAX 10
int lcs( int dp[MAX][MAX][MAX], int arr1[], int n,
int arr2[], int m, int k)
{
if (k < 0)
return -1e7;
if (n < 0 || m < 0)
return 0;
int & ans = dp[n][m][k];
if (ans != -1)
return ans;
ans = max(lcs(dp, arr1, n - 1, arr2, m, k),
lcs(dp, arr1, n, arr2, m - 1, k));
if (arr1[n-1] == arr2[m-1])
ans = max(ans, 1 + lcs(dp, arr1, n - 1,
arr2, m - 1, k));
ans = max(ans, 1 + lcs(dp, arr1, n - 1,
arr2, m - 1, k - 1));
return ans;
}
int main()
{
int k = 1;
int arr1[] = { 1, 2, 3, 4, 5 };
int arr2[] = { 5, 3, 1, 4, 2 };
int n = sizeof (arr1) / sizeof (arr1[0]);
int m = sizeof (arr2) / sizeof (arr2[0]);
int dp[MAX][MAX][MAX];
memset (dp, -1, sizeof (dp));
cout << lcs(dp, arr1, n, arr2, m, k) << endl;
return 0;
}
|
Java
import java.util.*;
import java.io.*;
class GFG
{
static int MAX = 10 ;
static int lcs( int [][][] dp, int [] arr1,
int n, int [] arr2, int m, int k)
{
if (k < 0 )
return - 10000000 ;
if (n < 0 || m < 0 )
return 0 ;
int ans = dp[n][m][k];
if (ans != - 1 )
return ans;
try
{
ans = Math.max(lcs(dp, arr1, n - 1 , arr2, m, k),
lcs(dp, arr1, n, arr2, m - 1 , k));
if (arr1[n - 1 ] == arr2[m - 1 ])
ans = Math.max(ans, 1 + lcs(dp, arr1, n - 1 ,
arr2, m - 1 , k));
ans = Math.max(ans, 1 + lcs(dp, arr1, n - 1 ,
arr2, m - 1 , k - 1 ));
} catch (Exception e) { }
dp[n][m][k] = ans;
return ans;
}
public static void main(String[] args)
{
int k = 1 ;
int [] arr1 = { 1 , 2 , 3 , 4 , 5 };
int [] arr2 = { 5 , 3 , 1 , 4 , 2 };
int n = arr1.length;
int m = arr2.length;
int [][][] dp = new int [MAX][MAX][MAX];
for ( int i = 0 ; i < MAX; i++)
for ( int j = 0 ; j < MAX; j++)
for ( int l = 0 ; l < MAX; l++)
dp[i][j][l] = - 1 ;
System.out.println(lcs(dp, arr1, n, arr2, m, k));
}
}
|
Python3
MAX = 10
def lcs(dp, arr1, n, arr2, m, k):
if k < 0 :
return - ( 10 * * 7 )
if n < 0 or m < 0 :
return 0
ans = dp[n][m][k]
if ans ! = - 1 :
return ans
ans = max (lcs(dp, arr1, n - 1 , arr2, m, k),
lcs(dp, arr1, n, arr2, m - 1 , k))
if arr1[n - 1 ] = = arr2[m - 1 ]:
ans = max (ans, 1 + lcs(dp, arr1, n - 1 ,
arr2, m - 1 , k))
ans = max (ans, lcs(dp, arr1, n - 1 ,
arr2, m - 1 , k - 1 ))
dp[n][m][k] = ans
return dp[n][m][k]
if __name__ = = "__main__" :
k = 1
arr1 = [ 1 , 2 , 3 , 4 , 5 ]
arr2 = [ 5 , 3 , 1 , 4 , 2 ]
n = len (arr1)
m = len (arr2)
dp = [[[ - 1 for i in range ( MAX )] for j in range ( MAX )] for k in range ( MAX )]
print (lcs(dp, arr1, n, arr2, m, k))
|
C#
using System;
class GFG
{
static int MAX = 10;
static int lcs( int [,,] dp, int [] arr1,
int n, int [] arr2,
int m, int k)
{
if (k < 0)
return -10000000;
if (n < 0 || m < 0)
return 0;
int ans = dp[n, m, k];
if (ans != -1)
return ans;
try
{
ans = Math.Max(lcs(dp, arr1, n - 1,
arr2, m, k),
lcs(dp, arr1, n,
arr2, m - 1, k));
if (arr1[n - 1] == arr2[m - 1])
ans = Math.Max(ans, 1 +
lcs(dp, arr1, n - 1,
arr2, m - 1, k));
ans = Math.Max(ans, 1 +
lcs(dp, arr1, n - 1,
arr2, m - 1, k - 1));
} catch (Exception e) { }
return ans;
}
public static void Main(String[] args)
{
int k = 1;
int [] arr1 = { 1, 2, 3, 4, 5 };
int [] arr2 = { 5, 3, 1, 4, 2 };
int n = arr1.Length;
int m = arr2.Length;
int [,,] dp = new int [MAX, MAX, MAX];
for ( int i = 0; i < MAX; i++)
for ( int j = 0; j < MAX; j++)
for ( int l = 0; l < MAX; l++)
dp[i, j, l] = -1;
Console.WriteLine(lcs(dp, arr1, n,
arr2, m, k));
}
}
|
Javascript
<script>
let MAX = 10;
function lcs(dp, arr1, n, arr2, m, k)
{
if (k < 0)
return -10000000;
if (n < 0 || m < 0)
return 0;
let ans = dp;
if (ans != -1)
return ans;
try
{
ans = Math.max(lcs(dp, arr1, n - 1, arr2, m, k),
lcs(dp, arr1, n, arr2, m - 1, k));
if (arr1[n - 1] == arr2[m - 1])
ans = Math.max(ans, 1 + lcs(dp, arr1, n - 1,
arr2, m - 1, k));
ans = Math.max(ans, 1 + lcs(dp, arr1, n - 1,
arr2, m - 1, k - 1));
} catch (e) { }
return ans;
}
let k = 0;
let arr1 = [ 1, 2, 3, 4, 5 ];
let arr2 = [ 5, 3, 1, 4, 2 ];
let n = arr1.length;
let m = arr2.length;
let dp = new Array(MAX);
for (let i = 0; i < MAX; i++)
for (let j = 0; j < MAX; j++)
for (let l = 0; l < MAX; l++)
dp = -1;
document.write(lcs(dp, arr1, n, arr2, m, k));
</script>
|
Time Complexity: O(N*M*K).
Auxiliary Space: O(MAX3)
If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
18 Sep, 2023
Like Article
Save Article