经典动态规划:最长公共子序列 :: labuladong的算法小抄 #1029
Replies: 14 comments
-
class Solution:
'''
问题等价: 求最长公共子序列的最大ASCII码值的和,
'''
def minimumDeleteSum(self, s1: str, s2: str) -> int:
dp = [[0]*(len(s2)+1) for _ in range(len(s1)+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]+ord(s1[i-1])
else:
dp[i][j]=max(dp[i-1][j],dp[i][j-1])
ascSum = 0
ascSum += sum([ord(char) for char in list(s1)])
ascSum += sum([ord(char) for char in list(s2)])
return ascSum - 2*dp[len(s1)][len(s2)] |
Beta Was this translation helpful? Give feedback.
-
1143.C++ class Solution {
public:
// 定义dp返回 text1从i, text2从j开始的公共子序列的长度
int dp(string text1, int i, string text2, int j, vector<vector<int>>& memo)
{
if(i==text1.length() || j==text2.length())
return 0;
if(memo[i][j] != -1)
return memo[i][j];
if(text1[i]==text2[j])
memo[i][j] = 1 + dp(text1, i+1, text2, j+1, memo);
else
{
memo[i][j] = max(dp(text1, i+1, text2, j, memo),
dp(text1, i, text2, j+1, memo));
}
return memo[i][j];
}
int longestCommonSubsequence(string text1, string text2) {
// 定义备忘录
vector< vector<int> > memo(text1.size(), vector<int>(text2.size(), -1));
return dp(text1, 0, text2, 0, memo);
}
};
力扣自顶而下居然超时, 定义了备忘录也会的吗呜呜呜~ |
Beta Was this translation helpful? Give feedback.
-
@kuangkuangkuangha 是你代码写得有问题吧,递归函数的参数怎么能传值呢?string 改成 string& 试试。 |
Beta Was this translation helpful? Give feedback.
-
@labuladong 雀氏哦,稳啊!传参数会拷贝的,内存大,耗时,牛蛙,谢谢啦! |
Beta Was this translation helpful? Give feedback.
-
712 两个字符串最小ASCII删除和 自底向上dp解法 public int minimumDeleteSum(String s1, String s2) {
int m = s1.length(), n = s2.length();
//s1[...i]和s2[...j]若要成为相等的字符串所需要删除的字符的ASCII值的最小和为dp[i][j]
int[][] dp = new int[m + 1][n + 1];
//base case
for (int i = 1; i <= m; i++) {
dp[i][0] = dp[i - 1][0] + s1.charAt(i - 1);
}
for (int j = 1; j <= n; j++) {
dp[0][j] = dp[0][j - 1] + s2.charAt(j - 1);
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; 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));
}
}
}
return dp[m][n];
} |
Beta Was this translation helpful? Give feedback.
-
打卡,感谢楼主! |
Beta Was this translation helpful? Give feedback.
-
请问怎么一上来就知道这题用dp的 |
Beta Was this translation helpful? Give feedback.
-
582 题的 js 解法,习惯用空白字符给两个字符串增加前缀,避免偏移量 /**
* @param {string} word1
* @param {string} word2
* @return {number}
*/
var minDistance = function (word1, word2) {
// 避免偏移量
word1 = " " + word1;
word2 = " " + word2;
const rows = word1.length;
const cols = word2.length;
// dp[i][j] 含义:到 i,j 位置时,使得字符串相同的最小步骤
const dp = new Array(rows)
.fill(0)
.map(() => new Array(cols).fill(Number.MAX_SAFE_INTEGER));
// init
dp[0][0] = 0; // 第一个字符相等,不需要操作
for (let row = 1; row < rows; row++) {
dp[row][0] = row;
}
for (let col = 1; col < cols; col++) {
dp[0][col] = col;
}
// tra
for (let row = 1; row < rows; row++) {
for (let col = 1; col < cols; col++) {
if (word1[row] === word2[col]) {
// 相等,不需要删除
dp[row][col] = dp[row - 1][col - 1];
} else {
const ifDeleteRow = dp[row][col - 1] + 1; // word2 不需要动
const ifDeleteCol = dp[row - 1][col] + 1; // word1 不需要动
dp[row][col] = Math.min(ifDeleteRow, ifDeleteCol);
}
}
}
return dp[rows - 1][cols - 1];
}; |
Beta Was this translation helpful? Give feedback.
-
LC.712 - DP 数组自底向上 class Solution {
public int minimumDeleteSum(String s1, String s2) {
int m = s1.length(), n = s2.length();
int[][] dp = new int[m+1][n+1];
for(int i = 1; i <= m; i++){
dp[i][0] = s1.charAt(i-1) + dp[i-1][0];
}
for(int j = 1; j <= n; j++){
dp[0][j] = s2.charAt(j-1) + dp[0][j-1];
}
for(int i = 1; i <= m; i++){
for(int j = 1; j <= n; 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));
}
}
}
return dp[m][n];
}
} |
Beta Was this translation helpful? Give feedback.
-
内存压缩版 class Solution {
// int[][] dp;
int[] dp;
public int longestCommonSubsequence(String text1, String text2) {
int m = text1.length(), n = text2.length();
// dp = new int[m+1][n+1];
dp = new int[n+1];
for(int i = 1; i <= m; i++) {
int pre = 0;
for(int j = 1; j <=n; j++) {
int temp = dp[j];
if(text1.charAt(i-1) == text2.charAt(j-1)){
// dp[i][j] = 1+ dp[i - 1][j - 1];
dp[j] = 1+pre;
}else {
// dp[i][j] = Math.max(dp[i][j - 1], dp[i - 1][j]);
dp[j] = Math.max(dp[j-1],dp[j]);
}
pre = temp;
}
}
return dp[n];
}
} |
Beta Was this translation helpful? Give feedback.
-
打卡打卡 |
Beta Was this translation helpful? Give feedback.
-
这种题还是用备忘录好理解一点,和编辑距离有点像 class Solution {
Integer[][] memo;
int m;
int n;
public int longestCommonSubsequence(String text1, String text2) {
m = text1.length();
n = text2.length();
memo = new Integer[m][n];
return dp(text1, 0, text2, 0);
}
/**
* text1[i:] 与 text2[j:] 的lcs
*/
private int dp(String text1, int i, String text2, int j) {
if (i == m || j == n) {
return 0;
}
if (memo[i][j] != null) {
return memo[i][j];
}
if (text1.charAt(i) == text2.charAt(j)) {
return memo[i][j] = 1 + dp(text1, i + 1, text2, j + 1);
}
return memo[i][j] = max(dp(text1, i + 1, text2, j), dp(text1, i, text2, j + 1));
}
private int max(int... nums) {
int max = nums[0];
for (int num : nums) {
max = Math.max(max, num);
}
return max;
}
} |
Beta Was this translation helpful? Give feedback.
-
class Solution {
private int[][] memo;
public int minDistance(String word1, String word2) {
memo=new int[word1.length()][word2.length()];
for(int[] m:memo){
Arrays.fill(m,-1);
}
return dp(word1,0,word2,0);
}
public int dp(String s1,int i,String s2,int j){
if(i==s1.length()){
return s2.length()-j;
}
if(j==s2.length()){
return s1.length()-i;
}
if(memo[i][j]!=-1){
return memo[i][j];
}
//相等无需删除,直接跳过
if(s1.charAt(i)==s2.charAt(j)){
memo[i][j]=dp(s1,i+1,s2,j+1);
}else{
//不相等进行删除
memo[i][j]=Math.min(
dp(s1,i+1,s2,j),
dp(s1,i,s2,j+1)
)+1;
}
return memo[i][j];
}
} |
Beta Was this translation helpful? Give feedback.
-
打卡,慢慢开始摸到门道 |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
文章链接点这里:经典动态规划:最长公共子序列
评论礼仪 见这里,违者直接拉黑。
Beta Was this translation helpful? Give feedback.
All reactions