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]
.
思路:
這是一道典型的動態規劃題目,建立二維數組dp,其中dp[i][j]表示字符串s1的前i個字符和字符串s2的前j個字符要變相等所需要刪除的字符的最小ASCII碼。
首先對dp進行初始化,當一個字符串為空時,另一個字符串需要刪除全部的字符串才能保證兩個字符串相等。
for (int i = 1; i <= (signed) s1.length(); i++) { dp[i][0] = dp[i - 1][0] + (int) s1[i - 1]; } for (int i = 1; i <= (signed) s2.length(); i++) dp[0][i] = dp[0][i - 1] + (int) s2[i - 1];
對於dp[i][j],一共有3三種方法到達dp[i][j]
當s1[i-1] == s2[j-1]時,不需要刪除s1[i-1]和s2[j-1]就可以保證兩個字符串相等,此時dp[i][j] = dp[i-1][j-1]
當s1[i-1] != s2[j-1]時,dp[i][j]可以等於dp[i-1][j]+s1[i-1],也可以等於dp[i][j-1]+s2[j-1]。
dp[i-1][j]+s1[i-1]表示由於從dp[i-1][j]到dp[i][j],增加了字符s1[i-1],s2的字符沒有變。想要相同,就必須刪除s1[i-1]。
dp[i][j-1]+s2[j-1]表示由於從dp[i][j-1]到dp[i][j],增加了字符s2[j-1],s1的字符沒有變。想要相同,就必須刪除s2[j-1]。
代碼:
1 #include<iostream> 2 #include<algorithm> 3 #include<string> 4 #include<vector> 5 using namespace std; 6 class Solution { 7 public: 8 int minimumDeleteSum(string s1, string s2) { 9 //dp[i][j]代表s1的前i個字符與s2的前j個字符相等所需要刪除的最小ascii碼 10 int dp[s1.length() + 1][s2.length() + 1] = { 0 }; 11 //初始化 12 for (int i = 1; i <= (signed) s1.length(); i++) { 13 dp[i][0] = dp[i - 1][0] + (int) s1[i - 1]; 14 } 15 for (int i = 1; i <= (signed) s2.length(); i++) 16 dp[0][i] = dp[0][i - 1] + (int) s2[i - 1]; 17 18 for (int i = 1; i <= (signed) s1.length(); i++) { 19 for (int j = 1; j <= (signed) s2.length(); j++) { 20 //字符相等,不需要刪除元素 21 if (s1[i - 1] == s2[j - 1]) 22 dp[i][j] = dp[i - 1][j - 1]; 23 else { 26 dp[i][j] = min(dp[i - 1][j] + (int) s1[i - 1], 27 dp[i][j - 1] + (int) s2[j - 1]); 28 } 29 cout << dp[i][j] << " "; 30 } 31 } 32 cout << endl; 33 return dp[s1.length()][s2.length()]; 34 } 35 };
舉例:
以sea和eat為例。
當i=1,j=1時,dp[1][1] = min(dp[0][1]+s1[0],dp[1][0]+s2[0]) = e+s = 216
dp[0][1]+s1[0]表示eat已經刪除了e,sea需要刪除s。
dp[1][0]+s2[0]表示sea已經刪除了s,eat需要刪除e。
當i=1,j=2時,dp[1][2] = min(dp[0][2]+s2[0],dp[1][1]+s2[1]) = min(ea+s,se+a) = a+e+s = 313
dp[0][2]+s2[0]表示eat已經刪除了ea,sea需要刪除s。
dp[1][1]+s2[1]表示sea已經刪除了s,eat已經刪除了e,需要刪除a。
當i=1,j=3時,dp[1][3] = min(dp[0][3]+s1[0],dp[1][2]+s2[2]) = min(eat+s,s+ea+t) = a+e+s+t = 429
dp[0][3]+s1[0]表示eat已經刪了eat,sea需要刪除s。
dp[1][2]+s2[2]表示sea已經刪除了s,eat已經刪除了ea,需要刪除t。
當i=2,j=1時,dp[2][1] = dp[1][0] = 115
由於s1[1]與s2[0]相同,只需要刪除sea中的s。
當i = 2,j = 2時,dp[2][2] = min(dp[1][2]+s1[1],dp[2][1]+s2[1]) = a+s = 212
dp[1][2]+s1[1]表示sea已經刪除了s,eat已經刪除了ea,sea還需要刪除e。
dp[2][1]+s2[1]表示sea已經刪除了s,eat還需要刪除a。
當i=2,j=3時,dp[2][3] = min(dp[1][3]+s1[1],dp[2][2]+s2[2]) = a+s+t = 328
dp[1][3]+s1[1]表示sea已經刪除了s,eat已經刪除了eat,sea還需要刪除e。
dp[2][2]+s2[2]表示sea已經刪除了s,eat已經刪除了a,eat還需要刪除t。
當i=3,j=1時,dp[3][1] = min(dp[2][1]+s1[2],dp[3][0]+s2[0]) = s+a = 212
dp[2][1]+s1[2]表示sea已經刪除了s,sea還需要刪除a。
dp[3][0]+s2[0]表示sea已經刪除了sea,eat還需要刪除a。
當i=3,j=2時,dp[3][2] = dp[2][1] = 115
當i=3,j=3時,dp[3][3] = min(dp[2][3]+s1[2],dp[3][2]+s2[2]) = s + t = 231
dp[3][2]+s2[2]表示sea已經刪除了s,eat還需要刪除t。
712. Minimum ASCII Delete Sum for Two Strings