Niuke.netブラッシングの質問-最も長い一般的な部分文字列

問題の説明

2つの文字列str1とstr2を指定して、2つの文字列の最長の共通部分文字列を出力します。最長の共通部分文字列が空の場合は、-1を出力します。

入力の説明:
2つの文字列を入力します

出力の説明:
最長の共通部分文字列を出力します

例1


「1AB2345CD」、「12345EF」と入力します

出力
「2345」

ソリューション

分析

  1. 最長共通部分列(最長共通部分列、略してLCS)は、非常に古典的なインタビューの質問です。これは、その解決策が典型的な2次元動的計画法であり、より難しい文字列問題のほとんどがこの質問に従うためです。
  2. メソッドの紹介
    (1)dp配列の定義:int [] [] dp = new int [m + 1] [n + 1];配列の値は、共通の文字列の長さです
    (2)aの割り当て2次元配列:
    ここに画像の説明を挿入
    (3)グラフから、最長の共通文字列の長さの式は次のようになります。dp[i + 1] [j + 1] = dp [i] [j] + 1

方法

  1. 2次元動的計画法+いくつかの最適化を使用します。

コード

// 思路1
public class Solution {
    
      
    public String LCS (String str1, String str2) {
    
    
        // write code here
        int m = str1.length(), n = str2.length();
        int[][] dp = new int[m + 1][n + 1];

		// 记录最长公共字串的长度
        int maxLen = 0;
        int index = 0;
        for (int i = 0; i < m; i++) {
    
    
            for (int j = 0; j < n; j++) {
    
    
                // 获取两个串字符
                char c1 = str1.charAt(i), c2 = str2.charAt(j);
                if (c1 == c2) {
    
    
                    // 运用二维动态规划总结的公式
                    dp[i + 1][j + 1] = dp[i][j] + 1;
                    if (dp[i + 1][j + 1] > maxLen) {
    
    
                        maxLen = dp[i + 1][j + 1];
                        // 记录最长公共字串结束的索引
                        index = j + 1;
                    }
                }
            }
        }

        if (maxLen == 0) {
    
    
            return "";
        }

        return str2.substring(index - maxLen, index);
    }
}

時間計算量分析:
O(MN):文字列をトラバースする2層ループ。したがって、時間計算量は文字列の長さの積です。

空間複雑性分析:
O(MN):追加の2次元配列を使用して、最長の共通文字列の長さを格納します。(m + 1)(n + 1)= mn + m + n + 1、mおよびnは無視される法則は一定であるため、空間の複雑さはMNです。

テストしたい場合は、Niuke.comのリンクに直接アクセスしてテストを行うことができます

最長の公開部分文字列

おすすめ

転載: blog.csdn.net/qq_35398517/article/details/113758113