最长公共子串

2年前 (2022) 程序员胖胖胖虎阿
379 0 0

目录

题目:

输入描述:

输出描述:

示例1

输入

输出

备注:

思路分析-未空间压缩:

思路分析-空间压缩:

代码展示:


题目:

给定两个字符串str1和str2,输出两个字符串的最长公共子串,如果最长公共子串为空,输出-1。

输入描述:

输入包括两行,第一行代表字符串srr1,第二行代表字符串str2。 1 ≤ length( str1), length(str2) ≤ 5000

输出描述:

输出包括一行,代表最长公共子串。

示例1

输入

1AB2345CD 12345EF

输出

2345

备注:

时间复杂度O(N^2),额外空间复杂度O(1)。(n可以为其中任意一个字符串长度)

思路分析-未空间压缩:

  1. 申请一个二维表dp[s2.length()][s1.length()]
    1. 行代表str2,索引i代表字符串当前字符str2[i]
    2. 列代表str1,索引j代表字符串当前字符str1[j]
    3. dp[i][j]代表 以str2[i]结尾的字串str2` 与 以str1[j]结尾的字串str1` 的最长公共字串
      1. 因为str1与str2的最长公共字串一定会以某个i某个j结尾,所以dp[i][j]中的最大值就是公共字串的长度
      2. 然后将最大长度处的索引向前推,就可以得到最长公共字串
      3. 为什么会这样定义,因为子串要求要连续,所以当以i,j结尾且str2[i] == str1[j]时,如果上一个是连续,则当前也一定连续
  2. 初始化
    1. 首行如果相等,则dp[i][j] = 1 否则dp[i][j] = 0
    2. 不用初始化首列,因为dp只依赖于左上角
  3. 其余点:
    1. 如果str2[i] == str1[j]则dp[i][j] = dp[i-1][j-1] + 1
    2. 否则dp[i][j] = 0
    3. 在填写dp时,更新最大值max,与最大值对应的i的索引值pos
  4. 根据最大长度与索引值还原最长子串

思路分析-空间压缩:

  1. 因为dp只依赖于左上角,所以不需要再申请一个二维表
  2. 只需要几个变量,从右上角点开始,划“捺”
    1. 定义出发点,出发点一开始时(0,m-1)
    2. 出发点向左移动,遇到边界后向下移动

最长公共子串

代码展示:

import java.io.*;

public class Main{
    public static void main(String[] args)throws IOException{
        BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
        String s1 = read.readLine();
        String s2 = read.readLine();
        int n = s2.length();
        int m = s1.length();
        int col = m-1;//出发点的列
        int row = 0;//出发点的行
        int max=0;//最大长度
        int pos = -1;//索引
        while(col!=0 || row < n){
            int i = row;
            int j = col;
            int len = 0;
            while(i<n && j<m){//划“捺”
                if(s1.charAt(j) == s2.charAt(i)){
                    len++;
                    if(len>max){
                        max = len;
                        pos = i;
                    }
                    
                }else{
                    len=0;
                }
                i++;
                j++;
            }
            if(col == 0){//出发点先左移到边界,再下移
                row++;
            }else{
                col--;
            }
        }
        String str = s2.substring(pos-max+1,pos+1);
        if(str.length()==0){
            str = "-1";
        }
        System.out.println(str);
    }
}
版权声明:程序员胖胖胖虎阿 发表于 2022年9月18日 下午6:56。
转载请注明:最长公共子串 | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...