2

I have read several Algorithm books where it is been told brute force approach of Longest Common Subsequence takes 2^n which is exponential in time complexity. Whereas, I've noticed that while I am applying my brute force technique it's taking O(mn) (from my personal observation). I would like to request you please read my approach clearly and visualize in mind and ask question for further clarification if needed. My Approach is following:- Say we have two strings s1 = "ECDGI" , s2 = "ABCDEFGHIJ". Now what I am doing is I chose either one of the given strings. For say, s1. for i = 1 to n (n is the last index of s1), I am taking each value and comparing with the s2 in such a way that for a single character of s1 I am checking with all the characters of s2. Mathematically, ith value is checking through all jth value up to m (m is the last index of s2). Here, if I find any common character I just move to next character from both strings. Then just compute subsequence. I compute all the possible subsequence for each characters from s1 by running n loops. Finally, I compute the largest value. From my understanding it's taking O(mn) time complexity overall. So My Question is, " Is my Time Complexity Calculation right ? "

Trace :

i = 1, value = E, lcs = 3 [EGI]

i = 2, value = C, lcs = 4 [CDGI]

i = 3, value = D, lcs = 3 [DGI]

i = 4, value = G, lcs = 2 [GI]

i = 5, value = I, lcs = 1 [I]

Answer is = 4 (maximum lcs)

My code is given below !

import java.util.*;
public class Main {
      static int count;
      static String s1 = "ECDGI"; // you can try with "EEE" or etc. 
      static String s2 = "ABCDEFGHIJ"; // you can try with "EEE" or etc.
  public static void main(String[] args) {
 LinkedList<Integer> ll = new LinkedList<>();
      for(int i =0; i<s1.length();i++){
      int t = i;
      count = 0; 
       for (int j=0; j<s2.length();j++){
         if(s1.charAt(t)==s2.charAt(j)){
           count++; 
            doIt(t+1,j+1);
            break ; 
        }
       }
        ll.add(count);
      }
      System.out.println(ll); // printing the whole LinkedList
      System.out.println(Collections.max(ll)); // taking the maximum value 
  }
  public static void doIt(int a, int b){
 for ( ; a<s1.length(); a++){
        int t = b ; 
        for (; t<s2.length(); t++){
          if (s1.charAt(a) == s2.charAt(t)){
           count++; 
           b=t+1; 
           break ; 
           }
        }
     }
  }

}

1 Answers1

2
  1. Your algorithm is wrong. Consider the case when s1 = "AABAA" and s2 = "AAAAB", your code gives 3, but LCS is 4.

  2. Time complexity is O(n * m * (n+m))

    • Why?

    • Well let`s consider worst case where we have s1 is n/2 'A' characters and n/2 'B' characters, and s2 is m/2 'A' characters and m/2 'C' characters

    • Now if we ignore doIt() function loops themselves give O(n * m)
    • So how many times doIt() is called? well for all pairs of n/2 first characters of s1 and m/2 of s2 so n/2 * m/2 times, or if we drop constants O(n * m ) times
    • Now lets analyze complexity of doIt()
    • It Uses something like 2 pointers to pass both strings so its complexity is O(n+m)
    • So total complexity is O(n * m * (n+m)) or O(n^2 * m + m^2 * n)
Photon
  • 2,717
  • 1
  • 18
  • 22
  • thanks a lot. Actually my understanding about LCS was wrong. By the way can you please tell me why it's 2^n for LCS brute force technique. ? – Shahriar Mim Mar 17 '19 at 17:44
  • 1
    Well brute force would be something like https://stackoverflow.com/questions/9010479/how-to-find-the-longest-common-subsequence-in-exponential-time so if you analyse the recursion, in worst case we keep having 2 recursive calls per step so it's something like 2^max(n, m) in worst case (for better understanding try drawing recursion call tree yourself for small strings) – Photon Mar 17 '19 at 17:57
  • Dear Photon, if you don't mind can we be friend on social medias ? or can you please give me your email address ? Actually, I need a mate to learn algorithm correctly. I have posted the same question on several platforms, among them you are the only one who help me to learn this LCS algorithm correctly and accurately which eventually cleared up my all queries. – Shahriar Mim Mar 21 '19 at 14:18
  • @ShahriarMim Sure, here`s my discord tag: Photon_#0381 – Photon Mar 21 '19 at 15:14
  • Done ! I had sent you a request ! my tag is ShahriarMim – Shahriar Mim Mar 21 '19 at 19:24