Given two strings X and Y of length m and n respectively. The problem is to find the length of the longest common subsequence of strings X and Y which contains all vowel characters.
Examples:
Input : X = "aieef"
Y = "klaief"
Output : aie
Input : X = "geeksforgeeks"
Y = "feroeeks"
Output : eoee
Source: Paytm Interview Experience ( Backend Developer ).
Naive Approach: Generate all subsequences of both given sequences and find the longest matching subsequence which contains all vowel characters. This solution is exponential in term of time complexity.
Efficient Approach (Dynamic Programming): This approach is a variation to Longest Common Subsequence | DP-4 problem.
The difference in this post is just that the common subsequence characters must all be vowels.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
bool isVowel( char ch)
{
if (ch == 'a' || ch == 'e' || ch == 'i'
|| ch == 'o' || ch == 'u' )
return true ;
return false ;
}
int lcs( char * X, char * Y, int m, int n)
{
int L[m + 1][n + 1];
int i, j;
for (i = 0; i <= m; i++) {
for (j = 0; j <= n; j++) {
if (i == 0 || j == 0)
L[i][j] = 0;
else if ((X[i - 1] == Y[j - 1]) && isVowel(X[i - 1]))
L[i][j] = L[i - 1][j - 1] + 1;
else
L[i][j] = max(L[i - 1][j], L[i][j - 1]);
}
}
return L[m][n];
}
int main()
{
char X[] = "aieef" ;
char Y[] = "klaief" ;
int m = strlen (X);
int n = strlen (Y);
cout << "Length of LCS = "
<< lcs(X, Y, m, n);
return 0;
}
|
Java
class GFG
{
static boolean isVowel( char ch)
{
if (ch == 'a' || ch == 'e' ||
ch == 'i' || ch == 'o' ||
ch == 'u' )
return true ;
return false ;
}
static int lcs(String X, String Y,
int m, int n)
{
int L[][] = new int [m + 1 ][n + 1 ];
int i, j;
for (i = 0 ; i <= m; i++)
{
for (j = 0 ; j <= n; j++)
{
if (i == 0 || j == 0 )
L[i][j] = 0 ;
else if ((X.charAt(i - 1 ) == Y.charAt(j - 1 )) &&
isVowel(X.charAt(i - 1 )))
L[i][j] = L[i - 1 ][j - 1 ] + 1 ;
else
L[i][j] = Math.max(L[i - 1 ][j],
L[i][j - 1 ]);
}
}
return L[m][n];
}
public static void main(String[] args)
{
String X = "aieef" ;
String Y = "klaief" ;
int m = X.length();
int n = Y.length();
System.out.println( "Length of LCS = " +
lcs(X, Y, m, n));
}
}
|
Python3
def isVowel(ch):
if (ch = = 'a' or ch = = 'e' or
ch = = 'i' or ch = = 'o' or
ch = = 'u' ):
return True
return False
def lcs(X, Y, m, n):
L = [[ 0 for i in range (n + 1 )]
for j in range (m + 1 )]
i, j = 0 , 0
for i in range (m + 1 ):
for j in range (n + 1 ):
if (i = = 0 or j = = 0 ):
L[i][j] = 0
elif ((X[i - 1 ] = = Y[j - 1 ]) and
isVowel(X[i - 1 ])):
L[i][j] = L[i - 1 ][j - 1 ] + 1
else :
L[i][j] = max (L[i - 1 ][j],
L[i][j - 1 ])
return L[m][n]
X = "aieef"
Y = "klaief"
m = len (X)
n = len (Y)
print ( "Length of LCS =" , lcs(X, Y, m, n))
|
C#
using System;
class GFG
{
static int isVowel( char ch)
{
if (ch == 'a' || ch == 'e' ||
ch == 'i' || ch == 'o' ||
ch == 'u' )
return 1;
return 0;
}
static int max( int a, int b)
{
return (a > b) ? a : b;
}
static int lcs(String X, String Y,
int m, int n)
{
int [,]L = new int [m + 1, n + 1];
int i, j;
for (i = 0; i <= m; i++)
{
for (j = 0; j <= n; j++)
{
if (i == 0 || j == 0)
L[i, j] = 0;
else if ((X[i - 1] == Y[j - 1]) &&
isVowel(X[i - 1]) == 1)
L[i, j] = L[i - 1, j - 1] + 1;
else
L[i, j] = max(L[i - 1, j],
L[i, j - 1]);
}
}
return L[m, n];
}
static public void Main(String []args)
{
String X = "aieef" ;
String Y = "klaief" ;
int m = X.Length;
int n = Y.Length;
Console.WriteLine( "Length of LCS = " +
lcs(X, Y, m, n));
}
}
|
Javascript
<script>
function isVowel(ch)
{
if (ch == 'a' || ch == 'e' ||
ch == 'i' || ch == 'o' ||
ch == 'u' )
return true ;
return false ;
}
function lcs(X, Y, m, n)
{
let L = new Array(m + 1);
let i, j;
for (i = 0; i <= m; i++)
{
L[i] = new Array(n + 1);
for (j = 0; j <= n; j++)
{
if (i == 0 || j == 0)
L[i][j] = 0;
else if ((X[i - 1] == Y[j - 1]) &&
isVowel(X[i - 1]))
L[i][j] = L[i - 1][j - 1] + 1;
else
L[i][j] = Math.max(L[i - 1][j],
L[i][j - 1]);
}
}
return L[m][n];
}
let X = "aieef" ;
let Y = "klaief" ;
let m = X.length;
let n = Y.length;
document.write( "Length of LCS = " + lcs(X, Y, m, n));
</script>
|
PHP
<?php
function isVowel( $ch )
{
if ( $ch == 'a' || $ch == 'e' ||
$ch == 'i' || $ch == 'o' || $ch == 'u' )
return true;
return false;
}
function lcs( $X , $Y , $m , $n )
{
$L = array_fill (0, $m + 1, array_fill (0, $n + 1, NULL));
for ( $i = 0; $i <= $m ; $i ++)
{
for ( $j = 0; $j <= $n ; $j ++)
{
if ( $i == 0 || $j == 0)
$L [ $i ][ $j ] = 0;
else if (( $X [ $i - 1] == $Y [ $j - 1]) &&
isVowel( $X [ $i - 1]))
$L [ $i ][ $j ] = $L [ $i - 1][ $j - 1] + 1;
else
$L [ $i ][ $j ] = max( $L [ $i - 1][ $j ],
$L [ $i ][ $j - 1]);
}
}
return $L [ $m ][ $n ];
}
$X = "aieef" ;
$Y = "klaief" ;
$m = strlen ( $X );
$n = strlen ( $Y );
echo "Length of LCS = " . lcs( $X , $Y , $m , $n );
?>
|
Complexity Analysis:
- Time Complexity: O(m*n).
- Auxiliary Space: O(m*n).
Efficient approach : Space optimization
In previous approach the current value dp[i][j] is only depend 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:
C++
#include <bits/stdc++.h>
using namespace std;
bool isVowel( char ch)
{
if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u' )
return true ;
return false ;
}
int lcs( char * X, char * Y, int m, int n)
{
vector< int > dp(n + 1, 0);
for ( int i = 1; i <= m; i++) {
int prev = 0;
for ( int j = 1; j <= n; j++) {
int curr = dp[j];
if ((X[i - 1] == Y[j - 1]) && isVowel(X[i - 1]))
dp[j] = prev + 1;
else
dp[j] = max(dp[j], dp[j - 1]);
prev = curr;
}
}
return dp[n];
}
int main()
{
char X[] = "aieef" ;
char Y[] = "klaief" ;
int m = strlen (X);
int n = strlen (Y);
cout << "Length of LCS = " << lcs(X, Y, m, n);
return 0;
}
|
Java
import java.util.Arrays;
public class GFG {
public static boolean isVowel( char ch) {
return ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u' ;
}
public static int lcs( char [] X, char [] Y, int m, int n) {
int [] dp = new int [n + 1 ];
for ( int i = 1 ; i <= m; i++) {
int prev = 0 ;
for ( int j = 1 ; j <= n; j++) {
int curr = dp[j];
if (X[i - 1 ] == Y[j - 1 ] && isVowel(X[i - 1 ]))
dp[j] = prev + 1 ;
else
dp[j] = Math.max(dp[j], dp[j - 1 ]);
prev = curr;
}
}
return dp[n];
}
public static void main(String[] args) {
char [] X = "aieef" .toCharArray();
char [] Y = "klaief" .toCharArray();
int m = X.length;
int n = Y.length;
System.out.println( "Length of LCS = " + lcs(X, Y, m, n));
}
}
|
Python3
def isVowel(ch):
if ch = = 'a' or ch = = 'e' or ch = = 'i' or ch = = 'o' or ch = = 'u' :
return True
return False
def lcs(X, Y, m, n):
dp = [ 0 ] * (n + 1 )
for i in range ( 1 , m + 1 ):
prev = 0
for j in range ( 1 , n + 1 ):
curr = dp[j]
if X[i - 1 ] = = Y[j - 1 ] and isVowel(X[i - 1 ]):
dp[j] = prev + 1
else :
dp[j] = max (dp[j], dp[j - 1 ])
prev = curr
return dp[n]
X = "aieef"
Y = "klaief"
m = len (X)
n = len (Y)
print ( "Length of LCS =" , lcs(X, Y, m, n))
|
C#
using System;
public class GFG {
static bool IsVowel( char ch) {
if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u' )
return true ;
return false ;
}
static int LCSWithVowels( char [] X, char [] Y, int m, int n) {
int [] dp = new int [n + 1];
for ( int i = 1; i <= m; i++) {
int prev = 0;
for ( int j = 1; j <= n; j++) {
int curr = dp[j];
if (X[i - 1] == Y[j - 1] && IsVowel(X[i - 1]))
dp[j] = prev + 1;
else
dp[j] = Math.Max(dp[j], dp[j - 1]);
prev = curr;
}
}
return dp[n];
}
static void Main( string [] args) {
char [] X = "aieef" .ToCharArray();
char [] Y = "klaief" .ToCharArray();
int m = X.Length;
int n = Y.Length;
Console.WriteLine( "Length of LCS = " + LCSWithVowels(X, Y, m, n));
}
}
|
Javascript
function isVowel(ch) {
if (ch === 'a' || ch === 'e' || ch === 'i' ||
ch === 'o' || ch === 'u' )
return true ;
return false ;
}
function lcs(X, Y, m, n) {
let dp = new Array(n + 1).fill(0);
for (let i = 1; i <= m; i++) {
let prev = 0;
for (let j = 1; j <= n; j++) {
let curr = dp[j];
if (X[i - 1] === Y[j - 1] && isVowel(X[i - 1]))
dp[j] = prev + 1;
else
dp[j] = Math.max(dp[j], dp[j - 1]);
prev = curr;
}
}
return dp[n];
}
let X = "aieef" ;
let Y = "klaief" ;
let m = X.length;
let n = Y.length;
console.log( "Length of LCS =" , lcs(X, Y, m, n));
|
Time Complexity: O(m*n).
Auxiliary Space: O(n).
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 :
29 Aug, 2023
Like Article
Save Article