1. 程式人生 > >[LeetCode] 583. Delete Operation for Two Strings

[LeetCode] 583. Delete Operation for Two Strings

題目

Given two words word1 and word2, find the minimum number of steps required to make word1 and word2 the same, where in each step you can delete one character in either string.

Example 1:

Input: "sea", "eat"
Output: 2

Explanation: You need one step to make “sea” to “ea” and another step to make “eat” to “ea”. Note:

  1. The length of given words won’t exceed 500.
  2. Characters in given words can only be lower-case letters.

題目大意

刪除兩個字串的字元使它們相等,求最小的刪除數。

思路

轉換為 求兩個字串的最長公共子序列問題

動態規劃求解,這樣的考慮很明顯 因為 對於str1[0:p] 與 str2[0:k] 若 已經求得最長子序列,那麼 str1 與 str2 可從區域性的解中獲得全域性優解。

dp[i][j]狀態表示:S1 的前 i 個字元與 S2 的前 j 個字元最長公共子序列的長度。

狀態轉移:

根據 S1i

與 S2j 值是否相等,分為兩種情況:

  • 當 S1i==S2j 時,那麼就能在 S1 的前 i-1 個字元與 S2 的前 j-1 個字元最長公共子序列的基礎上再加上 S1i 這個值,最長公共子序列長度加 1,即 dp[i][j] = dp[i-1][j-1] + 1。
  • 當 S1i != S2j 時,此時最長公共子序列為 S1 的前 i-1 個字元和 S2 的前 j 個字元最長公共子序列,或者 S1 的前 i 個字元和 S2 的前 j-1 個字元最長公共子序列,取它們的最大者,即 dp[i][j] = max{ dp[i-1][j], dp[i][j-1] }。

狀態轉移方程:

	if(S1<
sub>
i</sub>==S2<sub>j</sub>) dp[i][j] = dp[i-1][j-1]+1; else dp[i][j] = Math.max(dp[i-1][j],dp[i][j-1]);

最後需要變化的 字元數為 n+m-2*dp[n][m]。

code:

class Solution {
    public int minDistance(String word1, String word2) {
        int n = word1.length(),m = word2.length();
        int [][] dp = new int[n+1][m+1];
        for(int i = 1;i < n+1;i++)
            for(int j = 1; j < m+1 ;j++){
                if(word1.charAt(i-1) == word2.charAt(j-1))
                    dp[i][j] = dp[i-1][j-1]+1;
                else
                    dp[i][j] = Math.max(dp[i-1][j],dp[i][j-1]);
            }
        return n+m-2*dp[n][m];
    }
}