Longest Common Subsequence with no repeating character
Last Updated :
24 May, 2022
Given two strings s1 and s2, the task is to find the length of the longest common subsequence with no repeating character.
Examples:
Input: s1= “aabbcc”, s2= “aabc”
Output: 3
Explanation: “aabc” is longest common subsequence but it has two repeating character ‘a’.
So the required longest common subsequence with no repeating character is “abc”.
Input: s1= “aabcad”, s2= “adbcwcad”
Output: 4
Explanation: The subsequences are “abcd” or “bcad”.
Approach: The approach to solve the problem is similar to that of the longest common subsequence using recursion but, also needs to keep track that no two characters are repeated in a subsequence. Follow the steps mentioned below:
- For each character at the ith position, that character can be part of a sequence or not.
- Generate every sequence in this way and check for the longest common sequence.
- To keep track of which characters are included in the subsequence use bits of variable “store”.
- Each bit of variable “store”, tells Whether that alphabet is already present or not in a subsequence.
- bit at 0th position corresponds to character ‘a’, at position 1 corresponds to ‘b’, similarly 2 to ‘c’ so on.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
int find(string s1, string s2, int N,
int M, long long store)
{
if (N == 0 || M == 0)
return 0;
if (s1[N - 1] == s2[M - 1]
&& ((store >> (s1[N - 1] - 'a' ))
& 1)
== 0) {
store = (store | (1 << (s1[N - 1]
- 'a' )));
return 1 + find(s1, s2, N - 1,
M - 1, store);
}
else
return max(find(s1, s2, N - 1, M,
store),
find(s1, s2, N, M - 1,
store));
}
int main()
{
string s1, s2;
s1 = "aabbcc" ;
s2 = "aabc" ;
long long store = 0;
cout << find(s1, s2, s1.length(),
s2.length(), store);
return 0;
}
|
Java
class GFG {
static int find(String s1, String s2, int N,
int M, int store) {
if (N == 0 || M == 0 )
return 0 ;
if (s1.charAt(N - 1 ) == s2.charAt(M - 1 )
&& ((store >> (s1.charAt(N - 1 ) - 'a' ))
& 1 ) == 0 ) {
store = (store | ( 1 << (s1.charAt(N - 1 ) - 'a' )));
return 1 + find(s1, s2, N - 1 , M - 1 , store);
}
else
return Math.max(find(s1, s2, N - 1 , M, store),
find(s1, s2, N, M - 1 , store));
}
public static void main(String args[]) {
String s1, s2;
s1 = "aabbcc" ;
s2 = "aabc" ;
int store = 0 ;
System.out.println(find(s1, s2, s1.length(), s2.length(), store));
}
}
|
Python3
def find(s1, s2, N, M, store):
if (N = = 0 or M = = 0 ):
return 0
if (s1[N - 1 ] = = s2[M - 1 ]
and ((store >> ( ord (s1[N - 1 ]) - ord ( 'a' )))
& 1 )
= = 0 ):
store = (store | ( 1 << ( ord (s1[N - 1 ]) - ord ( 'a' ))))
return 1 + find(s1, s2, N - 1 ,
M - 1 , store)
else :
return max (find(s1, s2, N - 1 , M,
store),
find(s1, s2, N, M - 1 ,
store))
if __name__ = = "__main__" :
s1 = "aabbcc"
s2 = "aabc"
store = 0
print (find(s1, s2, len (s1), len (s2), store))
|
C#
using System;
public class GFG
{
static int find( string s1, string s2, int N,
int M, int store)
{
if (N == 0 || M == 0)
return 0;
if (s1[N - 1] == s2[M - 1]
&& ((store >> (s1[N - 1] - 'a' ))
& 1)
== 0) {
store = (store | (1 << (s1[N - 1]
- 'a' )));
return 1 + find(s1, s2, N - 1,
M - 1, store);
}
else
return Math.Max(find(s1, s2, N - 1, M,
store),
find(s1, s2, N, M - 1,
store));
}
public static void Main(String[] args)
{
string s1, s2;
s1 = "aabbcc" ;
s2 = "aabc" ;
int store = 0;
Console.Write(find(s1, s2, s1.Length,
s2.Length, store));
}
}
|
Javascript
<script>
function find(s1, s2, N,
M, store) {
if (N == 0 || M == 0)
return 0;
if (s1[N - 1] == s2[M - 1]
&& ((store >> (s1[N - 1].charCodeAt(0) - 'a' .charCodeAt(0)))
& 1) == 0) {
store = (store | (1 << (s1[N - 1].charCodeAt(0) - 'a' .charCodeAt(0)
)));
return 1 + find(s1, s2, N - 1,
M - 1, store);
}
else
return Math.max(find(s1, s2, N - 1, M,
store),
find(s1, s2, N, M - 1,
store));
}
let s1, s2;
s1 = "aabbcc" ;
s2 = "aabc" ;
let store = 0;
document.write(find(s1, s2, s1.length,
s2.length, store));
</script>
|
Time Complexity: O(N * 2N) where N is max(size of s1, size of s2).
Auxiliary Space: O(1)
Efficient approach: An efficient approach is to use memoization to reduce the time complexity. Create a 2D dp[][] array where dp[i][j] stores the length of the longest common subsequence with no repeating character till ith index of s1 and jth index of s2 is considered. If characters at s1[i] and s2[j] are same then dp[i][j] = dp[i-1][j-1] + 1, otherwise dp[i][j] = max(dp[i-1][j], dp[i][j-1]). Just keep track of repeating characters as mentioned in the above approach along with this.
Note: In the implementation, the dp array is implemented using map where the key is the concatenated string of i and j.
Given below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
map<string, int > mp;
int find(string s1, string s2, int N, int M,
long long store)
{
if (N == 0 || M == 0)
return 0;
string temp = to_string(N) + '#'
+ to_string(M) + '#'
+ to_string(store);
if (mp.find(temp) != mp.end())
return mp[temp];
if (s1[N - 1] == s2[M - 1]
&& ((store >> (s1[N - 1] - 'a' ))
& 1)
== 0) {
store = (store | (1 << (s1[N - 1]
- 'a' )));
return mp[temp]
= 1 + find(s1, s2, N - 1,
M - 1, store);
}
else
return mp[temp]
= max(find(s1, s2, N - 1,
M, store),
find(s1, s2, N, M - 1,
store));
}
int main()
{
string s1, s2;
s1 = "aabbcc" ;
s2 = "aabc" ;
long long store = 0;
cout << find(s1, s2, s1.length(),
s2.length(), store);
return 0;
}
|
Java
import java.util.*;
class GFG
{
private static HashMap<String, Integer> mp = new HashMap<>();
static int find(String s1, String s2, int N, int M, int store)
{
if (N == 0 || M == 0 )
return 0 ;
String temp = String.valueOf(N) + '#'
+ String.valueOf(M) + '#'
+ String.valueOf(store);
if (mp.containsKey(temp))
return mp.get(temp);
if (s1.charAt(N - 1 ) == s2.charAt(M - 1 )
&& ((store >> (s1.charAt(N - 1 ) - 'a' ))
& 1 )
== 0 ) {
store = (store | ( 1 << (s1.charAt(N - 1 )- 'a' )));
mp.put(temp, 1 + find(s1, s2, N - 1 ,M - 1 , store));
return mp.get(temp);
}
else
{ mp.put(temp,Math.max(find(s1, s2, N - 1 ,
M, store),
find(s1, s2, N, M - 1 ,
store)));
return mp.get(temp); }
}
public static void main(String args[]) {
String s1, s2;
s1 = "aabbcc" ;
s2 = "aabc" ;
int store = 0 ;
System.out.println(find(s1, s2, s1.length(), s2.length(), store));
}
}
|
Python3
mp = {}
def find(s1,s2,N,M,store):
if (N = = 0 or M = = 0 ):
return 0
temp = str (N) + '#' + str (M) + '#' + str (store)
if (temp in mp):
return mp[temp]
if (s1[N - 1 ] = = s2[M - 1 ] and ((store >> ( ord (s1[N - 1 ]) - ord ( 'a' ))) & 1 ) = = 0 ):
store = (store | ( 1 << ( ord (s1[N - 1 ]) - ord ( 'a' ))))
mp[temp] = 1 + find(s1, s2, N - 1 ,M - 1 , store)
return mp[temp]
else :
mp[temp] = max (find(s1, s2, N - 1 ,M, store),find(s1, s2, N, M - 1 ,store))
return mp[temp]
s1 = "aabbcc"
s2 = "aabc"
store = 0
print (find(s1, s2, len (s1), len (s2), store))
|
C#
using System;
using System.Collections;
using System.Collections.Generic;
class GFG {
static Dictionary< string , int > mp
= new Dictionary< string , int >();
static int find( string s1, string s2, int N, int M,
long store)
{
if (N == 0 || M == 0)
return 0;
string temp = N.ToString() + '#' + M.ToString()
+ '#' + store.ToString();
if (mp.ContainsKey(temp)) {
return mp[temp];
}
if (s1[N - 1] == s2[M - 1]
&& ((store >> (s1[N - 1] - 'a' )) & 1) == 0) {
store = (store | (1 << (s1[N - 1] - 'a' )));
return mp[temp]
= 1 + find(s1, s2, N - 1, M - 1, store);
}
else
return mp[temp]
= Math.Max(find(s1, s2, N - 1, M, store),
find(s1, s2, N, M - 1, store));
}
public static void Main()
{
string s1 = "aabbcc" ;
string s2 = "aabc" ;
long store = 0;
Console.Write(
find(s1, s2, s1.Length, s2.Length, store));
}
}
|
Javascript
<script>
let mp = new Map();
function find(s1, s2, N, M,store)
{
if (N == 0 || M == 0)
return 0;
let temp = N.toString() + '#'
+ M.toString() + '#'
+ store.toString();
if (mp.has(temp))
return mp.get(temp);
if (s1[N - 1] == s2[M - 1]
&& ((store >> (s1.charCodeAt(N - 1) - 97))
& 1)
== 0) {
store = (store | (1 << (s1.charCodeAt(N - 1) - 97)));
mp.set(temp,1 + find(s1, s2, N - 1,M - 1, store));
return mp.get(temp);
}
else {
mp.set(temp,Math.max(find(s1, s2, N - 1,M, store),find(s1, s2, N, M - 1,store)));
return mp.get(temp);
}
}
let s1 = "aabbcc" ;
let s2 = "aabc" ;
let store = 0;
document.write(find(s1, s2, s1.length, s2.length, store));
</script>
|
Time Complexity: O(N * M) where N is the size of s1 and M is the size of s2
Auxiliary Space: O(N * M)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...