mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-08-06 18:24:23 +08:00
3.6 KiB
3.6 KiB
142. 两个字符串的最小 ASCII 删除总和
本题和代码随想录:两个字符串的删除操作 思路基本是一样的。
属于编辑距离问题,如果想彻底了解,建议看看「代码随想录」的编辑距离总结篇。
本题dp数组含义:
dp[i][j] 表示 以i-1为结尾的字符串word1,和以j-1位结尾的字符串word2,想要达到相等,所需要删除元素的最小ASCII 删除总和。
如果 s1[i - 1] 与 s2[j - 1] 相同,则不用删:dp[i][j] = dp[i - 1][j - 1]
如果 s1[i - 1] 与 s2[j - 1] 不相同,删word1 的 最小删除和: dp[i - 1][j] + s1[i - 1]
,删word2的最小删除和: dp[i][j - 1] + s2[j - 1]
取最小值: dp[i][j] = min(dp[i - 1][j] + s1[i - 1], dp[i][j - 1] + s2[j - 1])
#include <iostream>
#include <vector>
using namespace std;
int main() {
string s1, s2;
cin >> s1 >> s2;
vector<vector<int>> dp(s1.size() + 1, vector<int>(s2.size() + 1, 0));
// s1 如果变成空串的最小删除ASCLL值综合
for (int i = 1; i <= s1.size(); i++) dp[i][0] = dp[i - 1][0] + s1[i - 1];
// s2 如果变成空串的最小删除ASCLL值综合
for (int j = 1; j <= s2.size(); j++) dp[0][j] = dp[0][j - 1] + s2[j - 1];
for (int i = 1; i <= s1.size(); i++) {
for (int j = 1; j <= s2.size(); j++) {
if (s1[i - 1] == s2[j - 1]) dp[i][j] = dp[i - 1][j - 1];
else dp[i][j] = min(dp[i - 1][j] + s1[i - 1], dp[i][j - 1] + s2[j - 1]);
}
}
cout << dp[s1.size()][s2.size()] << endl;
}
Java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String s1 = scanner.nextLine();
String s2 = scanner.nextLine();
int[][] dp = new int[s1.length() + 1][s2.length() + 1];
// s1 如果变成空串的最小删除ASCII值综合
for (int i = 1; i <= s1.length(); i++) {
dp[i][0] = dp[i - 1][0] + s1.charAt(i - 1);
}
// s2 如果变成空串的最小删除ASCII值综合
for (int j = 1; j <= s2.length(); j++) {
dp[0][j] = dp[0][j - 1] + s2.charAt(j - 1);
}
for (int i = 1; i <= s1.length(); i++) {
for (int j = 1; j <= s2.length(); j++) {
if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] = Math.min(dp[i - 1][j] + s1.charAt(i - 1), dp[i][j - 1] + s2.charAt(j - 1));
}
}
}
System.out.println(dp[s1.length()][s2.length()]);
scanner.close();
}
}
python
def min_delete_sum(s1: str, s2: str) -> int:
dp = [[0] * (len(s2) + 1) for _ in range(len(s1) + 1)]
# s1 如果变成空串的最小删除ASCII值综合
for i in range(1, len(s1) + 1):
dp[i][0] = dp[i - 1][0] + ord(s1[i - 1])
# s2 如果变成空串的最小删除ASCII值综合
for j in range(1, len(s2) + 1):
dp[0][j] = dp[0][j - 1] + ord(s2[j - 1])
for i in range(1, len(s1) + 1):
for j in range(1, len(s2) + 1):
if s1[i - 1] == s2[j - 1]:
dp[i][j] = dp[i - 1][j - 1]
else:
dp[i][j] = min(dp[i - 1][j] + ord(s1[i - 1]), dp[i][j - 1] + ord(s2[j - 1]))
return dp[len(s1)][len(s2)]
if __name__ == "__main__":
s1 = input().strip()
s2 = input().strip()
print(min_delete_sum(s1, s2))