1. 程式人生 > >【Leetcode】583.Delete Operation for Two Strings

【Leetcode】583.Delete Operation for Two Strings

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.

解析

題目要求,求出如何能快速的使得word1word2兩個單詞變成一樣的。這題是考察最長公共子序列(LCS)的應用,求出LCS,然後使用

word1.length+word2.length-2lcs即可求得結果。

兩種解題思路,第一種是比較熟悉的動態規劃:

建立狀態轉移方程,dp[i][j],用來記錄word1【0,i】word2中索引[0,j]中的LCS

  • word1[i-1]==word2[j-1]
    時,dp[i][j]=dp[i-1][j-1]
  • 否則dp[i][j] = 1 + Math.min(dp[i - 1][j], dp[i][j - 1]),相當於退而求次,如果i-1j-1位置不相等,那麼我們使得word1,word2向後退一步,用ij-1或者i-1j來比較。

第二種,使用記憶化+遞迴

建立一個遞迴函式來求解LCS,一個二維陣列來存放[m,n]位置的LCS長度,為了避免重複遞迴計算,我們可以將之前算得的LCS返回。

程式碼

記憶化+遞迴

 public static int minDistance(String word1, String word2) {
        int
mem[][] = new int[word1.length()+1][word2.length()+1]; return word1.length() + word2.length() - 2 * lcs(word1, word2, word1.length(), word2.length(), mem); } private static int lcs(String s1, String s2, int m, int n, int[][] mem) { if (m == 0 || n == 0) { return 0; } if (mem[m][n] > 0) { return mem[m][n]; } if (s1.charAt(m - 1) == s2.charAt(n - 1)) { mem[m][n] = 1 + lcs(s1, s2, m - 1, n - 1, mem); } else { mem[m][n] = Math.max(lcs(s1, s2, m, n - 1, mem), lcs(s1, s2, m - 1, n, mem)); } return mem[m][n]; }

動態規劃

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