簡體   English   中英

LCS 的蠻力方法及其時間復雜度 [O(m*n)!?]

[英]Brute Force Approach for LCS and its Time Complexity [O(m*n)!?]

我已經閱讀了幾本算法書籍,其中被告知最長公共子序列的蠻力方法需要 2^n,這是時間復雜度的指數。 然而,我注意到,當我應用我的蠻力技術時,它需要 O(m n)(根據我的個人觀察)。 我想請您清楚地閱讀我的方法並在腦海中想象一下,如果需要,請提出問題以進一步澄清。 我的方法如下:- 假設我們有兩個字符串s1 = "ECDGI" , s2 = "ABCDEFGHIJ"。 現在我正在做的是我選擇了給定的字符串之一。 比如說,s1。 對於 i = 1 到 n( n是 s1 的最后一個索引),我取每個值並與 s2 進行比較,以便對於 s1 的單個字符,我正在檢查 s2 的所有字符。 從數學上講,第 i 個值正在檢查所有第 j 個值,直到 m( m是 s2 的最后一個索引)。 在這里,如果我找到任何共同的字符,我就會從兩個字符串中移到下一個字符。 然后只需計算子序列。 我通過運行n 個循環來計算 s1 中每個字符的所有可能子序列。 最后,我計算最大值。 根據我的理解,它總體上需要 O(m n) 時間復雜度。 所以我的問題是, “我的時間復雜度計算是否正確?”

痕跡 :

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

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

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

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

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

答案是 = 4(最大 lcs)

我的代碼如下!

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. 你的算法是錯誤的。 考慮 s1 = "AABAA" 和 s2 = "AAAAB" 的情況,您的代碼給出 3,但 LCS 為 4。

  2. 時間復雜度為 O(n * m * (n+m))

    • 為什么?

    • 好吧,讓我們考慮最壞的情況,其中 s1 是 n/2 個“A”字符和 n/2 個“B”字符,而 s2 是 m/2 個“A”字符和 m/2 個“C”字符

    • 現在如果我們忽略 doIt() 函數循環本身給 O(n * m)
    • 那么 doIt() 被調用了多少次呢? 對於 s1 的所有 n/2 個第一個字符和 s2 的 m/2 對,所以 n/2 * m/2 次,或者如果我們刪除常數 O(n * m ) 次
    • 現在讓我們分析 doIt() 的復雜性
    • 它使用類似 2 個指針的東西來傳遞兩個字符串,所以它的復雜度是 O(n+m)
    • 所以總復雜度是 O(n * m * (n+m)) 或 O(n^2 * m + m^2 * n)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM