Skip to content
Related Articles
Open in App
Not now

Related Articles

Longest Common Subsequence with no repeating character

Improve Article
Save Article
  • Difficulty Level : Medium
  • Last Updated : 24 May, 2022
Improve Article
Save Article

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)

 


My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!