Open In App

Longest Common Subsequence with no repeating character

Last Updated : 24 May, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

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




// C++ program to implement the approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find lcs
// with no repeating character
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));
}
 
// Driver code
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




// Java program for the above approach
class GFG {
 
  // Function to find lcs
  // with no repeating character
  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));
  }
 
  // Driver Code
  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));
  }
}
 
// This code is contributed by gfgking


Python3




# python3 program to implement the approach
 
# Function to find lcs
# with no repeating character
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))
 
# Driver code
if __name__ == "__main__":
 
    s1 = "aabbcc"
    s2 = "aabc"
 
    store = 0
    print(find(s1, s2, len(s1), len(s2), store))
 
# This code is contributed by rakeshsahni


C#




// C# program for the above approach
using System;
 
public class GFG
{
 
// Function to find lcs
// with no repeating character
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));
}
 
// Driver Code
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));
}
}
 
// This code is contributed by code_hunt.


Javascript




<script>
       // JavaScript code for the above approach
 
       // Function to find lcs
       // with no repeating character
       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));
       }
 
       // Driver code
       let s1, s2;
       s1 = "aabbcc";
       s2 = "aabc";
 
       let store = 0;
       document.write(find(s1, s2, s1.length,
           s2.length, store));
 
      // This code is contributed by Potta Lokesh
   </script>


 
 

Output

3

 

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




// C++ program to implement the approach
#include <bits/stdc++.h>
using namespace std;
 
// Map for memoization
map<string, int> mp;
 
// Function to find lcs
// with no repeating character
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 the characters are same
    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);
    }
 
    // if the characters are different
    else
        return mp[temp]
               = max(find(s1, s2, N - 1,
                          M, store),
                     find(s1, s2, N, M - 1,
                          store));
}
 
// Driver code
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




// Java program for the above approach
import java.util.*;
 
class GFG
{
 
  // Map for memoization
  private static HashMap<String, Integer> mp = new HashMap<>();
 
  // Function to find lcs
  // with no repeating character
  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 the characters are same
    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);
    }
 
    // if the characters are different
    else
    { mp.put(temp,Math.max(find(s1, s2, N - 1,
                                M, store),
                           find(s1, s2, N, M - 1,
                                store)));
     return mp.get(temp); }
  }
 
  // Driver Code
  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));
  }
}
 
// This code is contributed by Pushpesh Raj


Python3




# Python3 program to implement the approach
 
# Map for memoization
mp = {}
 
# Function to find lcs
# with no repeating character
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 the characters are same
   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]
 
    # if the characters are different
   else:
      mp[temp] = max(find(s1, s2, N - 1,M, store),find(s1, s2, N, M - 1,store))
      return mp[temp]
 
# Driver code
s1 = "aabbcc"
s2 = "aabc"
 
store = 0
print(find(s1, s2, len(s1),len(s2), store))
 
# This code is contributed by shinjanpatra


C#




// C# program to implement the approach
using System;
using System.Collections;
using System.Collections.Generic;
 
class GFG {
 
  // Map for memoization
  static Dictionary<string, int> mp
    = new Dictionary<string, int>();
 
  // Function to find lcs
  // with no repeating character
  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 the characters are same
    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);
    }
 
    // if the characters are different
    else
      return mp[temp]
      = Math.Max(find(s1, s2, N - 1, M, store),
                 find(s1, s2, N, M - 1, store));
  }
 
  // Driver code
  public static void Main()
  {
    string s1 = "aabbcc";
    string s2 = "aabc";
 
    long store = 0;
    Console.Write(
      find(s1, s2, s1.Length, s2.Length, store));
  }
}
 
// This code is contributed by Samim Hossain Mondal.


Javascript




<script>
 
// JavaScript program to implement the approach
 
 
// Map for memoization
let mp = new Map();
 
// Function to find lcs
// with no repeating character
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 the characters are same
    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);
    }
 
    // if the characters are different
    else{
        mp.set(temp,Math.max(find(s1, s2, N - 1,M, store),find(s1, s2, N, M - 1,store)));
        return mp.get(temp);
    }
}
 
// Driver code
 
let s1 = "aabbcc";
let s2 = "aabc";
 
let store = 0;
document.write(find(s1, s2, s1.length, s2.length, store));
 
// code is contributed by shinjanpatra
 
</script>


 
 

Output

3

 

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
Previous
Next
Share your thoughts in the comments

Similar Reads