1. 程式人生 > >583. Delete Operation for Two Strings(python+cpp)

583. Delete Operation for Two Strings(python+cpp)

題目:

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:
The length of given words won’t exceed 500.
Characters in given words can only be lower-case letters.

解釋:
可以對字串執行刪除字元操作,每次只能刪除一個字元。最少需要多少步可以讓兩個字串相等。
動態規劃
與712. Minimum ASCII Delete Sum for Two Strings類似
dp[i][j]表示s1的前i個字元和s2的前j個字元所需要進行操作的最小值
其實這道題目也可以用lcs(subsequence)做,參考718. Maximum Length of Repeated Subarray(python+cpp)

對lcs(subsequence的介紹)
python程式碼:

class Solution(object):
    def minDistance(self, word1, word2):
        """
        :type word1: str
        :type word2: str
        :rtype: int
        """
        def lcsubsequence(A, B):
            m=len(A)
            n=len(B)
            dp=[[0]*(n+1) for _ in
range(m+1)] for i in range(1,m+1): for j in range(1,n+1): if A[i-1]==B[j-1]: dp[i][j]=dp[i-1][j-1]+1 else: dp[i][j]=max(dp[i][j-1],dp[i-1][j]) return dp[m][n] m=len(word1) n=len(word2) if m==0 and n==0: return 0 elif m==0: return n elif n==0: return m else: return m+n-2*lcsubsequence(word1,word2)

c++程式碼:

class Solution {
public:
    int minDistance(string word1, string word2) {
        int m=word1.size(),n=word2.size();
        if (m==0 && n==0)
            return 0;
        else if(m==0)
            return n;
        else if(n==0)
            return m;
        return m+n-2*lcsubsequence(word1,word2);
    }
    int lcsubsequence(string A,string B)
    {
        int m=A.size();
        int n=B.size();
        vector<vector<int>> dp(m+1,vector<int>(n+1,0));
        for (int i=1;i<=m;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if (A[i-1]==B[j-1])
                {
                    dp[i][j]=dp[i-1][j-1]+1;
                }
                else
                    dp[i][j]=max(dp[i-1][j],dp[i][j-1]);    
            }
        }
        return dp[m][n];
    }
};

總結:
注意,如果求的是lcsubarray,則需要用一個maxLen來記錄當前最長的子串的長度,如果求的是lcsubsequence,則不需要用maxLen,直接返回dp[m][n]即可,當然用maxLen記錄也不錯,因為最後一定會遍歷到dp[m][n]的,只是比較大小和更新的時候會浪費時間。