712. Minimum ASCII Delete Sum for Two Strings - Medium

Description

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.

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

Analyze

虽然跟最短编辑距离很像,但明眼人应该一眼就看出来,这就是个最长子序列的变形题。求完最长子序列,然后用总ASCII和减掉两倍的最大子序列和即可。
动态规划的状态转移方程如下:

dp[i][j]=0dp[i1][j1]+s1[i]max{dp[i1][j],dp[i][j1]}i=0||j=0s1[i]=s2[j]s1[i]!=s2[j]

有了状态转移方程写代码思路很清晰的,so easy一遍过。

Code

    int minimumDeleteSum(string s1, string s2) {
        int m = s1.size();
        int n = s2.size();
        int** arr = new int*[m];
        for(int i = 0; i < m; ++i)
            arr[i] = new int[n];
        for(int i = 0; i < m; ++i) {
            if(s2[0] == s1[i] || (i && arr[i-1][0]))
                arr[i][0] = s2[0];
            else arr[i][0] = 0;
        }
        for(int j = 0; j < n; ++j) {
            if(s1[0] == s2[j] || (j && arr[0][j-1]))
                arr[0][j] = s1[0];
            else arr[0][j] = 0;
        }

        for(int i = 1; i < m; ++i) {
            for(int j = 1; j < n; ++j) {
                if(s1[i] == s2[j])
                    arr[i][j] = arr[i-1][j-1] + s1[i];
                else if(arr[i-1][j] >= arr[i][j-1])
                    arr[i][j] = arr[i-1][j];
                else arr[i][j] = arr[i][j-1];
            }
        }

        int sum = 0;
        for(string::iterator it = s1.begin(); it != s1.end(); ++it)
            sum += *it;
        for(string::iterator it = s2.begin(); it != s2.end(); ++it)
            sum += *it;
        return sum - 2*arr[m-1][n-1];
    }

Summary

又瞻仰了一下人家十行的代码,学习到的点如下:
1.我绕了个圈子
我先求了最大公共子序列再去减,殊不知转变一下思路可以有更直接的解法

//dp[i][j] is the cost for s1.substr(0,i) and s2.substr(0, j). 
//Note s1[i], s2[j] not included in the substring.

//Base case: dp[0][0] = 0
//target: dp[m][n]

if s1[i-1] = s2[j-1]   // no deletion
    dp[i][j] = dp[i-1][j-1];
else   // delete either s1[i-1] or s2[j-1]
    dp[i][j] = min(dp[i-1][j]+s1[i-1], dp[i][j-1]+s2[j-1]);

2.简化前面的步骤
漂亮的二维数组申请方法:

vector<vector<int>> dp(m+1, vector<int>(n+1, 0));

i=0或者j=0的时候i-1这样的下标肯定是越界的,因此我需要额外用两个循环处理初始状态。而大佬申请数组时就多了一行一列,并初始化为全0。多出来的行用一个循环初始化为s2(0,j)的ASCII和,列的处理类似不过做了更加简化的处理,而省掉了一个循环。
不得不说人家的状态转移方程就比我们考虑地更加简洁优雅,能照顾到初始状况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
checking whether the compiler supports GNU C++... yes checking whether g++ accepts -g... yes checking for g++ option to enable C++11 features... none needed checking dependency style of g++... gcc3 checking how to run the C preprocessor... gcc -std=gnu11 -E checking for x86_64-w64-mingw32-ranlib... no checking for ranlib... ranlib checking for x86_64-w64-mingw32-dlltool... no checking for dlltool... no checking for x86_64-w64-mingw32-ar... no checking for x86_64-w64-mingw32-lib... no checking for x86_64-w64-mingw32-link... no checking for ar... ar checking the archiver (ar) interface... ar checking dependency style of gcc -std=gnu11... gcc3 checking for x86_64-w64-mingw32-as... no checking for as... as checking whether dlltool supports --temp-prefix... yes checking whether to build a w32api package for Cygwin... no checking whether to build the Win32 libraries... yes checking whether to build the Win64 libraries... yes checking whether to build the WinARM32 libraries... no checking whether to build the WinARM64 libraries... no checking whether to use genlib... no checking whether to enable globbing... no checking whether to enable private exports... no checking whether to enable delay import libs... no checking what to provide as libmsvcrt.a... msvcrt-os checking whether to include support for Control Flow Guard... no checking whether to enable experimental features... no checking whether the compiler supports -municode... no checking for stdio.h... yes checking for stdlib.h... yes checking for string.h... yes checking for inttypes.h... yes checking for stdint.h... yes checking for strings.h... yes checking for sys/stat.h... yes checking for sys/types.h... yes checking for unistd.h... yes checking for _mingw_mac.h... no
06-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值