zoukankan      html  css  js  c++  java
  • 最长公共子串

    最长公共子串

    ​ 给定两个字符串str1和str2,返回两个字符串的最长公共子串。

    此处计算的是两个字符串的最长公共子串,子串不同于子序列,子串要求必须是一串连续的字符。

    方法一

    ​ 使用经典的动态规划方法,首先定义一个动态规划数组dp,dp[i][j]表示的含义是以在str1中第i个字符和str2中第j个字符结尾的最长公共字串的长度。那么状态转移表达式就是:

    ​ 1、如果str1[i] == str2[j]

    dp[i][j] = dp[i-1][j-1] + 1;
    

    ​ 2、如果str1[i] != str2[j]

    dp[i][j] = 0
    

    初始化:

    ​ 对于dp[i][0],如果str1[i] == str2[0],则dp[i][0] = 1;

    ​ 对于dp[0][j],如果str1[0] == str2[j],则dp[0][j] = 1;

    public static int longestCommonStr(String text1, String text2){
    
        int n = text1.length();
        int m = text2.length();
    
        int[][] dp = new int[n][m];
        int max_length = 0;
        for (int i = 0; i < text1.toCharArray().length; i++) {
    
            if (text1.charAt(i) == text2.charAt(0)){
                dp[i][0] = 1;
                max_length = 1;
            }
        }
        for (int j = 0;j < text2.toCharArray().length;j++){
    
            if (text2.charAt(j) == text1.charAt(0)){
                dp[0][j] = 1;
            }
        }
        for (int i = 1; i < n; i++) {
    
            for (int j = 1; j < m; j++) {
    
                if (text1.charAt(i) == text2.charAt(j)){
                    dp[i][j] = dp[i-1][j-1] + 1;
                }else {
                    dp[i][j] = 0;
                }
                max_length = max_length>dp[i][j]?max_length:dp[i][j];
            }
    
        }
        return max_length;
    }
    

    ​ 时间复杂度为O(n*m),空间复杂度为O(n*m)

    方法二

    ​ 优化上面算法的空间复杂度,将其由O(n*m)优化为常量级别的O(1)

    ​ 在上面,我们定义的状态转移数组,是一个二维矩阵,其中每一个元素代表的含义就是以在str1中第i个字符和str2中第j个字符结尾的最长公共字串的长度,而dp[i][j]的值要么是0,要么就是在状态转移矩阵其位置的左上方的那个值的基础上加1得到。

    ​ 比如字符串 "abcde" 和 "bebcd",它的状态转移矩阵是:

    b e b c d
    a 0 0 0 0 0
    b 1 0 1 0 0
    c 0 0 0 2 0
    d 0 0 0 0 3
    e 0 1 0 0 0

    ​ 如果按照上图中的斜线来计算的话,那么就无需再使用状态转移数组,而只需变量就可以了。

    ​ 在按照斜线进行计算之前,先定义一个变量len,它用于记录状态转移矩阵中当前位置的左上方位置的值,初始值为0,计算的过程中首先判断if str1[i] == str2[j]:

    ​ 如果相等,那么len++;否则len=0

    ​ 我们从右上方的斜线开始计算,然后依次向左移动,计算左边的斜线;当无法向左移动的时候,再向下移动,当最左下方的斜线计算完毕以后,整个计算就完毕了。

    public static int longestCommonStr2(String text1, String text2){
    
        int m = text1.length();
        int n = text2.length();
    
        int row = 0;
        int col = n - 1;
        int max_length = 0;
    
        while (row < m){
            int i = row;
            int j = col;
            int len = 0;
            while (j < n && i < m){
    
                if (text1.charAt(i) == text2.charAt(j)){
                    len++;
                }else {
                    len = 0;
                }
                j++;
                i++;
            }
            max_length = max_length > len ? max_length : len;
    
            if (col > 0){
                col--;
            }else {
                row++;
            }
        }
    
        return max_length;
    
    }
    

    ​ 此算法的空间复杂度为O(1)

  • 相关阅读:
    three.js_ "Failed to execute 'texImage2D' on 'WebGLRenderingContext': tainted canvases may not be loded."
    three.js为何如此奇妙
    npm install ERR! code E400/E404
    小程序_请求封装network
    css_input[checked]复选框去掉默认样式并添加新样式
    【CSS】凹槽的写法
    剑指Offer_编程题_6
    剑指Offer_编程题_5
    剑指Offer_编程题_4
    剑指Offer_编程题_3
  • 原文地址:https://www.cnblogs.com/yxym2016/p/14416071.html
Copyright © 2011-2022 走看看