LeetCode動的計画法の最長共通部分列

一緒に書く習慣をつけましょう!「ナゲッツデイリーニュープラン・4月アップデートチャレンジ」に参加して7日目です。クリックしてイベントの詳細をご覧ください

トピック

text12つの文字列と が与えられた場合、2つの文字列 text2の最長共通部分列の長さを返します。共通のサブシーケンスが存在しない場合に戻ります0

文字列のサブシーケンスは、文字の相対的な順序を変更せずに元の文字列から削除されたいくつかの文字(または文字列なし)で構成される新しい文字列です。

たとえば、はの"ace"サブシーケンスですが、のサブシーケンスでありません。2つの文字列の共通のサブシーケンスは、両方の文字列に共通するサブシーケンスです。"abcde""aec""abcde"

例1:

输入:text1 = "abcde", text2 = "ace" 
输出:3  
复制代码

説明:最長共通部分列は、であり"ace"、その長さは3です。

例2:

输入:text1 = "abc", text2 = "abc"
输出:3
复制代码

説明:最長共通部分列は、であり"abc"、その長さは3です。

例3:

输入:text1 = "abc", text2 = "def"
输出:0
复制代码

説明:2つのストリングには共通のサブシーケンスがありません。return 0。  

ヒント:

1 <= text1.length, text2.length <= 1000
text1 和 text2 仅由小写英文字符组成。
复制代码

答え

問題解決分析

問題解決のアイデア:

  1. 最長共通部分列問題は、典型的な2次元動的計画問題です。
  2. 状態遷移式は次のとおりです。
// text1.charAt(i - 1) == text2.charAt(j - 1)
dp[i][j] = dp[i - 1][j - 1] + 1;
// text1.charAt(i - 1) != text2.charAt(j - 1)
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
复制代码
  1. 最終的な戻り結果dp[m][n];

複雑さ:
時間の複雑さ:O(M*N)
空間の複雑さ:O(M*N)

問題解決コード

ソリューションコードは次のとおりです(コード内の詳細なコメント):


class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
            // 获取长度
            int m = text1.length(), n = text2.length();
            // 创建 dp
            int[][] dp = new int[m + 1][n + 1];
            for (int i = 1; i <= m; i++) {
                char c1 = text1.charAt(i - 1);
                for (int j = 1; j <= n; j++) {
                    char c2 = text2.charAt(j - 1);
                    if (c1 == c2) {
                        dp[i][j] = dp[i - 1][j - 1] + 1;
                    } else {
                        dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
                    }
                }
            }
            return dp[m][n];
    }
}
复制代码

送信後のフィードバック結果(このトピックは最適化されていないため、パフォーマンスは平均的です):

image.png

参考情報

おすすめ

転載: juejin.im/post/7084200685801046029