【问题标题】:Longest Common Substring最长公共子串
【发布时间】:2014-04-14 16:38:57
【问题描述】:

我们分别有两个字符串aba的长度大于等于b。我们必须找出最长的公共子串。如果有多个答案,那么我们必须输出 b 中较早出现的子字符串(早于其起始索引在前)。

注意:ab 的长度最大可达106

我尝试使用后缀数组查找最长的公共子字符串(使用快速排序对后缀进行排序)。对于有多个答案的情况,我尝试将所有公共子字符串压入堆栈中,这些子字符串等于最长公共子字符串的长度。

我想知道有没有更快的方法?

【问题讨论】:

  • 我认为DP在这里行不通,因为a和b的值很大。
  • 这个解决方案是O(a*b)。你不会做得更好。
  • 也许你应该试试suffix tree
  • 这个问题来自正在进行的比赛......

标签: algorithm substring suffix-array longest-substring


【解决方案1】:

构建字符串a$bsuffix tree,即a 与两个字符串中未出现的某些字符(如$)连接,然后与b 连接。一个(压缩的)后缀树可以在 O(|a|+|b|) 时间和内存中构建,并且有 O(|a|+|b|) 个节点。

现在,对于每个节点,我们知道它的深度(从根开始遍历树到该节点所获得的字符串的长度)。我们还可以跟踪两个布尔量:在a对应的构建阶段是否访问过这个节点,以及在b对应的构建阶段是否访问过它(例如,我们不妨构建这两个树分开,然后使用前序遍历合并它们)。现在,任务归结为找到在两个阶段都访问过的最深顶点,这可以通过单个前序遍历来完成。多个答案的情况应该很容易处理。

Wikipedia page 包含该技术的另一个(简要)概述。

【讨论】:

    【解决方案2】:

    这是最长的子串,你要找的是有没有重复的。 请仔细阅读它可能会有所帮助。 http://www.programcreek.com/2013/02/leetcode-longest-substring-without-repeating-characters-java/

    【讨论】:

      【解决方案3】:
      import java.util.Scanner;
        public class JavaApplication8 {
            public static int find(String s1,String s2){
              int n = s1.length();
              int m = s2.length();
              int ans = 0;
              int[] a = new int[m];
              int b[] = new int[m];
              for(int i = 0;i<n;i++){
                  for(int j = 0;j<m;j++){
                      if(s1.charAt(i)==s2.charAt(j)){
                         if(i==0 || j==0 )a[j] = 1;
                         else{
                             a[j] = b[j-1] + 1;
                         }
                         ans = Math.max(ans, a[j]);
                      }
      
                  }
                  int[] c = a;
                  a = b;
                  b = c;
              }
              return ans;
          }
          public static void main(String[] args) {
              Scanner sc = new Scanner(System.in);
              String s1 = sc.next();
              String s2 = sc.next();
              System.out.println(find(s1,s2));
          }
      
      }
      

      Time Complexity O(N) Space Complexity O(N)

      【讨论】:

        【解决方案4】:
        package main
        
        import (
            "fmt"
            "strings"
        )
        
        func main(){
            fmt.Println(lcs("CLCL","LCLC"))
        }
        
        func lcs(s1,s2 string)(max int,str string){
            str1 := strings.Split(s1,"")
            str2 := strings.Split(s2,"")
            fmt.Println(str1,str2)
        
            str = ""
            mnMatrix := [4][4]int{}
            for i:=0;i<len(str1);i++{
                for j:=0;j<len(str2);j++{
                    if str1[i]==str2[j]{
                        if i==0 || j==0 {
                            mnMatrix[i][j] = 1
                            max = 1
                            //str = str1[i]
                        }else{
                            mnMatrix[i][j] = mnMatrix[i-1][j-1]+1
                            max = mnMatrix[i][j]
                            str = ""
                            for k:=max;k>=1;k--{
                                str = str + str2[k]
                                //fmt.Println(str)
                            }
                        }
        
        
                    }else{
                        mnMatrix[i][j] = 0
                    }
                }
            }
            fmt.Println(mnMatrix)
            return max, str
        }
        
            enter code here
        

        【讨论】:

          猜你喜欢
          • 2016-06-03
          • 2010-11-28
          • 2014-03-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-09-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多