1. 程式人生 > 其它 >1143. 最長公共子序列(dp)1

1143. 最長公共子序列(dp)1

技術標籤:LeetCode

給定兩個字串text1 和text2,返回這兩個字串的最長公共子序列的長度。

一個字串的子序列是指這樣一個新的字串:它是由原字串在不改變字元的相對順序的情況下刪除某些字元(也可以不刪除任何字元)後組成的新字串。
例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。兩個字串的「公共子序列」是這兩個字串所共同擁有的子序列。

若這兩個字串沒有公共子序列,則返回 0。

示例 1:

輸入:text1 = "abcde", text2 = "ace"

輸出:3
解釋:最長公共子序列是 "ace",它的長度為 3。
示例 2:

輸入:text1 = "abc", text2 = "abc"
輸出:3
解釋:最長公共子序列是 "abc",它的長度為 3。
示例 3:

輸入:text1 = "abc", text2 = "def"
輸出:0
解釋:兩個字串沒有公共子序列,返回 0。

提示:

1 <= text1.length <= 1000
1 <= text2.length <= 1000
輸入的字串只含有小寫英文字元。

通過次數59,872提交次數98,741

解法一:動態規劃DP

複雜度分析

時間複雜度:O(m * n),其中 m 和 n 分別為 A 和 B 的 長度。
空間複雜度:O(m * n),其中 m 和 n 分別為 A 和 B 的 長度。

// java
class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
        int m = text1.length(), n = text2.length();
        int[][] dp = new int[m + 1][n + 1];

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                // 獲取兩個串字元
                char c1 = text1.charAt(i), c2 = text2.charAt(j);
                if (c1 == c2) {
                    // 去找它們前面各退一格的值加1即可
                    dp[i + 1][j + 1] = dp[i][j] + 1;
                } else {
                    //要麼是text1往前退一格,要麼是text2往前退一格,兩個的最大值
                    dp[i + 1][j + 1] = Math.max(dp[i + 1][j], dp[i][j + 1]);
                }
            }
        }
        return dp[m][n];
    }
}