1. 程式人生 > 實用技巧 >1143. 最長公共子序列

1143. 最長公共子序列

一、題目描述:

給定兩個字串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、定義狀態:

假設 2 個序列分別是 nums1、nums2

  • i ∈ [1, nums1.length]
  • j ∈ [1, nums2.length]

假設 dp(i, j) 是【nums1 前 i 個元素】與【nums2 前 j 個元素】的最長公共子序列長度

2、狀態轉移方程:

如果 nums1[i – 1] = nums2[j – 1],那麼 dp(i, j) = dp(i – 1, j – 1) + 1

如果 nums1[i – 1] ≠ nums2[j – 1],那麼 dp(i, j) = max { dp(i – 1, j), dp(i, j – 1) }

3、初始值:

dp(i, 0)、dp(0, j) 初始值均為 0

4、最終結果:

dp[nums1.length,nums2.length]

三、程式碼:

使用一維陣列

class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
        if (text1 == null
|| text2 == null) { return 0; } int[] dp = new int[text2.length() + 1]; for (int i = 1; i <= text1.length(); i++) { int cur = 0; for (int j = 1; j <= text2.length(); j++) { int leftTop = cur; cur = dp[j]; if (text1.charAt(i - 1) == text2.charAt(j - 1)) { dp[j] = leftTop + 1; } else { dp[j] = Math.max(dp[j - 1], dp[j]); } } } return dp[text2.length()]; } }