Leetcode個人題解712

LEETCODE專題


712. Minimum ASCII Delete Sum for Two Strings

題目要求:
這裏寫圖片描述

這裏題目要求我們求出輸入的兩個字符串的“最小刪除距離”。所謂“刪除距離”,也就是將兩個字符串中除最長匹配序列以外的其它字符刪除的“距離”,也就是ascii碼值。而“最小刪除距離”是指在刪除的過程中,有可能存在不同的最長匹配序列,譬如題目所給的第2個例子中:

Input: s1 = "delete", s2 = "leet"

對於這兩個字符串,可以找到3個最長匹配序列:”let”、”lee”和”eet”。每一個保留的最長匹配序列及其對應的刪除距離如下表所示:

保留序列 最長距離
let 403
lee 433
eet 417

所以,可以得到的”最小刪除距離“是403。


問題:

  1. 這個問題的子問題是什麼?得到了子問題後如何複用子問題的結果?

思路:

  1. 我們可以得到這是一個前綴問題:匹配的序列位於2個字符串的前面。若結果存儲的剛好是最小刪除距離,那麼計算當前下標的匹配序列就可以判斷當前下標的兩個字符串的字符是否匹配,若匹配,我們可以不刪除這2個字符,複用之前的結果就可以了,當然也可以同時刪除掉這2個字符再加上之前的結果;若不匹配,我們可以選擇刪除第一個字符串中的當前字符,也可以選擇刪除第二個字符串中的當前字符所得到的結果分別加上對應的之前的結果。這幾種情況計算得出的最小值就是我們要求的結果。
  2. 此外,關於上述的如何判斷的問題,代碼中有比較詳細的註釋,就不在此一一贅述了。

下面直接上代碼:

class Solution {
public:
    int minimumDeleteSum(string s1, string s2) {
        /*
         * Initialize a 2-D array to store the minimumDeleteSum
         * of the substrings of these 2 strings with the first
         * index the length of the substring of the s1 and the
         * second one the length of the substring of the s2.
         *
         * There is 3 ways we can use to get the current
         * minimumDeleteSum, named minDeleteLength[i][j]
         * 1. minDeleteLength[i][j] = minDeleteLength[i - 1][j] + s1[i - 1]
         * that means the first i - 1 chars of s1 and the first
         * j chars of s2 are matched better, and s1[i - 1]
         * should be deleted.
         *
         * 2. minDeleteLength[i][j] = minDeleteLength[i][j - 1] + s2[j - 1]
         * that means the first i chars of s1 and the first
         * j - 1 chars of s2 are matched better, and s1[i - 1]
         * should be deleted.
         *
         * 3. minDeleteLength[i][j] = minDeleteLength[i - 1][j - 1]( + s1[i - 1] + s2[j - 1])
         * that means now s1[i - 1] and s2[j - 1] should both
         * be deleted, if s1[i -1] and s2[j - 1] are matched,
         * then we can omit the deleteLength of s1[i - 1] and
         * s2[j - 1], else we must add them.
        */
        int ** minDeleteLength = new int*[s1.length() + 1];
        int i, j, min;
        for (i = 0; i < s1.length() + 1; i++) {
            minDeleteLength[i] = new int[s2.length() + 1];
        }
        minDeleteLength[0][0] = 0;

        for (i = 0; i < s1.length() + 1; i++) {
            for (j = 0; j < s2.length() + 1; j++) {
                if (i == 0 && j == 0) {
                    continue;
                } else if (i == 0 && j != 0) {
                    minDeleteLength[0][j] = minDeleteLength[0][j - 1] + s2[j - 1];
                } else if (i != 0 && j == 0) {
                    minDeleteLength[i][0] = minDeleteLength[i - 1][0] + s1[i - 1];
                } else {
                    int t1, t2, t3;
                    t1 = minDeleteLength[i - 1][j] + s1[i - 1];
                    t2 = minDeleteLength[i][j - 1] + s2[j - 1];
                    min = t1 < t2 ? t1 : t2;
                    if (s1[i - 1] == s2[j - 1]) {
                        t3 = minDeleteLength[i - 1][j - 1];
                    } else {
                        t3 = minDeleteLength[i - 1][j - 1] + s1[i - 1] + s2[j - 1];
                    }
                    minDeleteLength[i][j] = min < t3 ? min : t3;
                }
            }
        }
        min = minDeleteLength[s1.length()][s2.length()];

        for (i = 0; i < s1.length() + 1; i++) {
            delete []minDeleteLength[i];
        }
        delete []minDeleteLength;

        return min;
    }
};

時間複雜度:O(n^2)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章