zoukankan      html  css  js  c++  java
  • [Coding Made Simple] Longest Common Substring

    Given two strings, find longest common substring between them.

    Solution 1. Brute force search, O(n^2 * m), O(1) memory

    Algorithm.

    O(n^2) runtime to find all substrings from string A. For each substring, it takes O(m) time to check if it exists in string B.

     1 public class Solution {
     2     public int longestCommonSubstring(String A, String B) {
     3         if(A == null || B == null || A.length() == 0 || B.length() == 0){
     4             return 0;
     5         }
     6         int max = Integer.MIN_VALUE;
     7         for(int i = 0; i < A.length(); i++){
     8             for(int j = i + 1; j <= A.length(); j++){
     9                 if(B.indexOf(A.substring(i, j)) >= 0){
    10                     max = Math.max(max, j - i);                    
    11                 }
    12                 else{
    13                     break;
    14                 }
    15             }
    16         }
    17         return max;
    18     }
    19 }

    Solution 2. Dynamic Programming, O(n * m) runtime, O(n * m) space

    Solution 1 is not efficient in that each time a substring is checked, it always start from index 0 of string B. The previous check

    result of smaller substrings are not used at all. For example, if A[i...j] is a substring in B, then in order to check if A[i...j + 1] is 

    a substring of B or not, we just need to check if the next character of substring A[i...j] in B equals to A[j + 1] or not. This only takes

    O(1) time. But in solution 1 there is no memorization of previous results, so it takes O(m) time for each check.

    State:

    lcs[i][j]:  the length of the common substring that ends at A[i - 1] and B[j - 1].

    Function:

    lcs[i][j] = 1 + lcs[i - 1][j - 1],  if A[i - 1] == B[j - 1];

    lcs[i][j] = 0, if A[i - 1] != B[j - 1];

    Initialization:

    lcs[i][0] = 0; lcs[0][j] = 0;

    Answer:

    max value of lcs[i][j]

     1 public class Solution {
     2     public int longestCommonSubstring(String A, String B) {
     3         if(A == null || B == null || A.length() == 0 || B.length() == 0){
     4             return 0;
     5         }    
     6         int n = A.length();
     7         int m = B.length();
     8         int[][] lcs = new int[n + 1][m + 1];
     9         for(int i = 0; i <= n; i++){
    10             lcs[i][0] = 0;
    11         }
    12         for(int j = 0; j <= m; j++){
    13             lcs[0][j] = 0;
    14         }
    15         for(int i = 1; i <= n; i++){
    16             for(int j = 1; j <= m; j++){
    17                 if(A.charAt(i - 1) == B.charAt(j - 1)){
    18                     lcs[i][j] = lcs[i - 1][j - 1] + 1;    
    19                 }
    20                 else{
    21                     lcs[i][j] = 0;
    22                 }
    23             }
    24         }
    25         int max = Integer.MIN_VALUE;
    26         for(int i = 1; i <= n; i++){
    27             for(int j = 1; j <= m; j++){
    28                 max = Math.max(max, lcs[i][j]);
    29             }
    30         }
    31         return max;
    32     }
    33 }

    Follow up question: Find one longest common substring.

    Answer: find the max value in lcs[i][j]; then go diagonal top left one grid at a time, until the value of the grid is 0.

    Related Problems

    Longest Common Subsequence

  • 相关阅读:
    SpringBoot国际化和国际化失败的原因
    java之上传文件、下载文件
    java之拦截器Interceptor/自定义视图解析器
    idea配置tomcat,idea和tomcat版本不一致输出json会报500错误,解决localhost:8080 is already in use问题,解决idea控制台日志乱码
    guzzle json 请求
    Testlib-Generator使用笔记
    Harbour.Space Scholarship Contest 2021-2022 (Div. 1 + Div. 2) 题解 (ABCDEF)
    Codeforces Round #731 (Div. 3) 题解 (DEFG)
    面试题
    yaml部署
  • 原文地址:https://www.cnblogs.com/lz87/p/7288815.html
Copyright © 2011-2022 走看看