最长的公共子串

时间:2014-03-11 07:51:00

标签: algorithm substring suffix-array longest-substring

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

注意:ab的长度最多可达10 6

我尝试使用后缀数组找到最长的公共子字符串(使用quicksort对后缀进行排序)。对于有多个答案的情况,我尝试推送堆栈中所有常见的子串,这些子串等于最长公共子串的长度。

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

4 个答案:

答案 0 :(得分:3)

构建字符串a$b的{​​{3}},即a与某些字符串联,例如$字符串中没有出现,然后与{{1}连接}。 (压缩的)后缀树可以在O(| a | + | b |)时间和内存中构建,并且具有O(| a | + | b |)节点。

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

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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)

答案 3 :(得分:0)

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