[WXM] LeetCode 712. Minimum ASCII Delete Sum for Two Strings C++

712. Minimum ASCII Delete Sum for Two Strings

Given two strings s1, s2, find the lowest ASCII sum of deleted characters to make two strings equal.

Example 1:

Input: s1 = "sea", s2 = "eat"
Output: 231
Explanation: Deleting "s" from "sea" adds the ASCII value of "s" (115) to the sum.
Deleting "t" from "eat" adds 116 to the sum.
At the end, both strings are equal, and 115 + 116 = 231 is the minimum sum possible to achieve this.

Example 2:

Input: s1 = "delete", s2 = "leet"
Output: 403
Explanation: Deleting "dee" from "delete" to turn the string into "let",
adds 100[d]+101[e]+101[e] to the sum.  Deleting "e" from "leet" adds 101[e] to the sum.
At the end, both strings are equal to "let", and the answer is 100+101+101+101 = 403.
If instead we turned both strings into "lee" or "eet", we would get answers of 433 or 417, which are higher.

Note:

  • 0 < s1.length, s2.length <= 1000.
  • All elements of each string will have an ASCII value in [97, 122].

Approach

  1. 题目大意是从两个字符串中找到最长公共子序并且它们的ASCII和最大sum,然后返回两个字符串中的字符ASCII的和-sum,这道题算是最长公共子序列问题的变形,你不仅要计算出最长公子序列dp数组,然后回溯找到最大的和,当然你也可以一步搞定。这里我就省略求dp数组,直接讲回溯求值思路,单纯的回溯求值会超时,我还加了cache数组用来记忆过程,也就是记忆化搜索,熟悉dp数组运作过程就很容易找到最长公共子序列,我们分几个过程,当s1[i]==s2[j]时候,那么ij都要往后减1,当dp[i][j-1]>=dp[i-1][j]时,那么j要往后减一,反之i要往后减一,这些操作是根据动态转移方程反向求解,但是最长公共子序列可不止一个,我们还要从中找到最大的,所以我们还要细分当dp[i][j-1]==dp[i-1][j]时,我们该i-1还是j-1呢,所以这里就存在求最值的过程,剩余的看代码理解。

Code

class Solution {
public:
    vector<vector<int>> LCS(string &s1, string &s2, int &n, int &m) {
        vector<vector<int>> dp(n + 1, vector<int>(m + 1, 1));
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if (s1[i - 1] == s2[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;
    }
    int DFS(string &s1, string &s2, int n, int m, vector<vector<int>> &dp, vector<vector<int>>&cache) {
        if (n < 1 && m < 1)return 0;
        if (cache[n][m] != -1)return cache[n][m];
        if (n > 0 && m > 0 && s1[n - 1] == s2[m - 1]) {
            cache[n][m] = DFS(s1, s2, n - 1, m - 1, dp, cache);
            return cache[n][m];
        }
        else if (n > 0 && m > 0 && dp[n][m - 1] == dp[n - 1][m]) {
            cache[n][m] = min(DFS(s1, s2, n - 1, m, dp, cache) + s1[n - 1], DFS(s1, s2, n, m - 1, dp, cache) + s2[m - 1]);
            return cache[n][m];
        }
        else if (n>0 && dp[n][m] == dp[n - 1][m]) {
            cache[n][m] = DFS(s1, s2, n - 1, m, dp, cache) + s1[n - 1];
            return cache[n][m];
        }
        else {
            cache[n][m] = DFS(s1, s2, n, m - 1, dp, cache) + s2[m - 1];
            return cache[n][m];
        }
    }
    int minimumDeleteSum(string s1, string s2) {
        int n = s1.size(), m = s2.size();
        vector<vector<int>>dp = LCS(s1, s2, n, m);
        vector<vector<int>>cache(n + 1, vector<int>(m + 1, -1));
        return DFS(s1, s2, n, m, dp, cache);
    }
};

猜你喜欢

转载自blog.csdn.net/WX_ming/article/details/82107643