住建部网站资质查询中宏建设集团,云南最便宜的网站建设,软件定制,邢台网最新发布583. 两个字符串的删除操作 题目链接#xff1a;两个字符串的删除操作 题目描述#xff1a;给定两个单词 word1 和 word2 #xff0c;返回使得 word1 和 word2 **相同所需的最小步数。 每步 可以删除任意一个字符串中的一个字符。 动态规划#xff08;思路一#xff09;两个字符串的删除操作 题目描述给定两个单词 word1 和 word2 返回使得 word1 和 word2 **相同所需的最小步数。 每步 可以删除任意一个字符串中的一个字符。 动态规划思路一
本题和**动态规划1143.最长公共子序列**基本相同只要求出两个字符串的最长公共子序列长度即可那么除了最长公共子序列之外的字符都是必须删除的最后用两个字符串的总长度减去两个最长公共子序列的长度就是删除的最少步数。
class Solution {
public:int minDistance(string word1, string word2) {vectorvectorint dp(word1.size() 1, vectorint(word2.size() 1, 0));for (int i 1; i word1.size(); i) {for (int j 1; j word2.size(); j) {if (word1[i - 1] word2[j - 1])dp[i][j] dp[i - 1][j - 1] 1;elsedp[i][j] max(dp[i - 1][j], dp[i][j - 1]);}}return word1.size() word2.size() - 2*dp[word1.size()][word2.size()];}
};动态规划思路二
动规五部曲 确定dp数组dp table以及下标的含义 dp[i][j]以i-1为结尾的字符串word1和以j-1位结尾的字符串word2想要达到相等所需要删除元素的最少次数。 确定递推公式 当word1[i - 1] 与 word2[j - 1]相同的时候dp[i][j] dp[i - 1][j - 1]; 当word1[i - 1] 与 word2[j - 1]不相同的时候有三种情况 情况一删word1[i - 1]最少操作次数为dp[i - 1][j] 1 情况二删word2[j - 1]最少操作次数为dp[i][j - 1] 1 情况三同时删word1[i - 1]和word2[j - 1]操作的最少次数为dp[i - 1][j - 1] 2 那最后当然是取最小值所以当word1[i - 1] 与 word2[j - 1]不相同的时候递推公式dp[i][j] min({dp[i - 1][j - 1] 2, dp[i - 1][j] 1, dp[i][j - 1] 1}); dp[i]的初始化 从递推公式中可以看出来dp[i][0] 和 dp[0][j]是一定要初始化的。dp[i][0]word2为空字符串以i-1为结尾的字符串word1要删除多少个元素才能和word2相同呢很明显dp[i][0] i。dp[0][j]的话同理 确定遍历顺序 从递推公式 dp[i][j] min(dp[i - 1][j - 1] 2, min(dp[i - 1][j], dp[i][j - 1]) 1); 和dp[i][j] dp[i - 1][j - 1]可以看出dp[i][j]都是根据左上方、正上方、正左方推出来的。所以遍历的时候一定是从上到下从左到右这样保证dp[i][j]可以根据之前计算出来的数值进行计算。
class Solution {
public:int minDistance(string word1, string word2) {vectorvectorint dp(word1.size() 1, vectorint(word2.size() 1));for (int i 0; i word1.size(); i) dp[i][0] i;for (int j 0; j word2.size(); j) dp[0][j] j;for (int i 1; i word1.size(); i) {for (int j 1; j word2.size(); j) {if (word1[i - 1] word2[j - 1]) {dp[i][j] dp[i - 1][j - 1];} else {dp[i][j] min(dp[i - 1][j] 1, dp[i][j - 1] 1);}}}return dp[word1.size()][word2.size()];}
};时间复杂度: O(n * m)空间复杂度: O(n * m) 72. 编辑距离 题目链接编辑距离 题目描述给你两个单词 word1 和 word2 请返回将 word1 转换成 word2 所使用的最少操作数 。 你可以对一个单词进行如下三种操作 插入一个字符删除一个字符替换一个字符 解题思路 确定dp数组dp table以及下标的含义 dp[i][j] 表示以下标i-1为结尾的字符串word1和以下标j-1为结尾的字符串word2最近编辑距离为dp[i][j]。 确定递推公式 这一类问题基本是要分析两种情况 当s[i - 1] 与 t[j - 1]相等时if (word1[i - 1] word2[j - 1]) 那么说明不用任何编辑dp[i][j] 就应该是 dp[i - 1][j - 1]即dp[i][j] dp[i - 1][j - 1]; 当s[i - 1] 与 t[j - 1]不相等时if (word1[i - 1] ! word2[j - 1])此时就需要编辑了如何编辑呢 操作一word1删除一个元素那么就是以下标i - 2为结尾的word1 与 j-1为结尾的word2的最近编辑距离 再加上一个操作。即 dp[i][j] dp[i - 1][j] 1;操作二word2删除一个元素那么就是以下标i - 1为结尾的word1 与 j-2为结尾的word2的最近编辑距离 再加上一个操作。即 dp[i][j] dp[i][j - 1] 1;操作三替换元素word1替换word1[i - 1]使其与word2[j - 1]相同此时不用增删加元素。那么只需要一次替换的操作就可以让 word1[i - 1] 和 word2[j - 1] 相同。所以 dp[i][j] dp[i - 1][j - 1] 1;综上当 if (word1[i - 1] ! word2[j - 1]) 时取最小的即dp[i][j] min({dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]}) 1 。这里不考虑添加元素是因为这两个操作在确定编辑距离时其实是等效的对word1删除元素就相当是对word2添加元素。 dp数组如何初始化 从递推公式dp[i][j] dp[i - 1][j - 1] dp[i - 1][j]; 和 dp[i][j] dp[i - 1][j]; 中可以看出dp[i][j] 是从上方和左上方推导而来如图那么 dp[i][0] 和dp[0][j]是一定要初始化的。 dp[i][0] 表示以i-1为结尾的s可以随便删除元素出现空字符串的个数。那么dp[i][0]一定都是1因为也就是把以i-1为结尾的s删除所有元素出现空字符串的个数就是1。再来看dp[0][j]dp[0][j]空字符串s可以随便删除元素出现以j-1为结尾的字符串t的个数。那么dp[0][j]一定都是0s如论如何也变成不了t。 确定遍历顺序 从递推公式dp[i][j] dp[i - 1][j - 1] dp[i - 1][j]; 和 dp[i][j] dp[i - 1][j]; 中可以看出dp[i][j]都是根据左上方和正上方推出来的。
class Solution {
public:int minDistance(string word1, string word2) {vectorvectorint dp(word1.size() 1,vectorint(word2.size() 1, 0));for (int i 0; i word1.size(); i)dp[i][0] i;for (int j 0; j word2.size(); j)dp[0][j] j;for (int i 1; i word1.size(); i) {for (int j 1; j word2.size(); j) {if (word1[i - 1] word2[j - 1])dp[i][j] dp[i - 1][j - 1];elsedp[i][j] min(min(dp[i - 1][j] 1, dp[i][j - 1] 1),dp[i - 1][j - 1] 1);}}return dp[word1.size()][word2.size()];}
};时间复杂度: O(n * m)空间复杂度: O(n * m)