問題の説明
2つの文字列str1とstr2を指定して、2つの文字列の最長の共通部分文字列を出力します。最長の共通部分文字列が空の場合は、-1を出力します。
入力の説明:
2つの文字列を入力します
出力の説明:
最長の共通部分文字列を出力します
例
例1
「1AB2345CD」、「12345EF」と入力します
出力
「2345」
ソリューション
分析
- 最長共通部分列(最長共通部分列、略してLCS)は、非常に古典的なインタビューの質問です。これは、その解決策が典型的な2次元動的計画法であり、より難しい文字列問題のほとんどがこの質問に従うためです。
- メソッドの紹介
(1)dp配列の定義:int [] [] dp = new int [m + 1] [n + 1];配列の値は、共通の文字列の長さです
(2)aの割り当て2次元配列:
(3)グラフから、最長の共通文字列の長さの式は次のようになります。dp[i + 1] [j + 1] = dp [i] [j] + 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のリンクに直接アクセスしてテストを行うことができます