算法学习day56

这篇具有很好参考价值的文章主要介绍了算法学习day56。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.力扣583. 两个字符串的删除操作

1.1 题目描述

题目描述:

给定两个单词word1和word2,找到使得word1和word2相同所需要的的最小步数,每步可以删除任意一个字符串的一个字符。

例:

输入:“sea”,“eat”

输出:2

解释:第一步将"sea"变为"ea",第二步将“eat”变成“ea”

1.2分析

1.确定dp数组以及下标含义

dp[i] [j] :以i-1为结尾的字符串word1和以j-1位结尾的字符串word2,想要达到相同,所需要删除元素的最少次数。

2.确定递推公式

(1)当word1[i-1]与word2[j-1]相同的时候

dp[i] [j] = dp[i - 1] dp[j-1]

(2)当word1[i-1]与word2[j-1]不相同的时候

​ (2.1)删word1[i-1],最少操作次数为dp[i-1] [j] + 1

​ (2.2)删word2[j-1],最少操作次数为dp[i] [j-1] +1

​ (2.3)同时删除word1[i-1]和word2[j-1],操作的最少次数为dp[i-1] [j-1]+2

取最小值,得递推公式:dp[i] [j] = min(min(dp[i-1] [j-1]+2,dp[i-1] [j]+1), dp[i] [j-1] + 1)

3.dp数组如何初始化

dp[i] [0]:word2为空字符串,以i-1为结尾的字符串word1需要删除多少个元素,才能和word2相同?显然dp[i] [0] = i

dp[0] [j]同理:

vector<vector<int>> dp(word1.size()+1,vector<int>(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;

4.确定遍历顺序

从上到下,从左到右。

5.举例推导dp数组
算法学习day56

1.3 代码

class Solution {
public:
    int minDistance(string word1, string word2) {
        // 创建动态规划数组,行数为 word1 的长度加一,列数为 word2 的长度加一
        vector<vector<int>> dp(word1.size() + 1, vector<int>(word2.size() + 1));
        
        // 初始化第一行和第一列
        for (int i = 0; i <= word1.size(); i++) dp[i][0] = i;  // 当 word2 为空时,将 word1 中的所有字符都删除,需要的操作数为 i
        for (int j = 0; j <= word2.size(); j++) dp[0][j] = j;  // 当 word1 为空时,将 word2 中的所有字符都插入到 word1 中,需要的操作数为 j
        
        // 递推计算 dp 数组中的其他元素
        for (int i = 1; i <= word1.size(); i++) {
            for (int j = 1; j <= word2.size(); j++) {
                if (word1[i - 1] == word2[j - 1]) {
                    // 如果 word1 的第 i 个字符和 word2 的第 j 个字符相同,那么将不需要进行操作
                    dp[i][j] = dp[i - 1][j - 1];
                } else {
                    // 当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
                    // 取这三种操作的最小值
                    dp[i][j] = min(min(dp[i-1][j-1]+2,dp[i-1][j]+1), dp[i][j-1] + 1);
                }
            }
        }
        
        // 返回 dp 数组的最后一个元素,即将 word1 转换为 word2 需要的最少操作数
        return dp[word1.size()][word2.size()];
    }
};

2.力扣72. 编辑距离

2.1 题目描述

题目描述:

给你两个单词word1和word2,请你计算出word1转换成word2所需要的最小操作数。

例1:

输入:word1 = “horse”, word2 = “ros”

输出:3

解释:horse -> rorse (将 ‘h’ 替换为 ‘r’) rorse -> rose (删除 ‘r’) rose -> ros (删除 ‘e’)

例2:

输入:word1 = “intention”, word2 = “execution”

输出:5

解释: intention -> inention (删除 ‘t’) inention -> enention (将 ‘i’ 替换为 ‘e’) enention -> exention (将 ‘n’ 替换为 ‘x’) exention -> exection (将 ‘n’ 替换为 ‘c’) exection -> execution (插入 ‘u’)

2.2 分析

1.确定dp数组以及下标的含义

dp[i] [j]表示以下标i-1为结尾的字符串word1和以下标j-1为结尾的字符串word2,最近的编辑距离为dp[i] [j].

2.确定递推公式

if(word1[i-1] == word23[j-1])
    不操作
if(word1[i-1] !=word2[j-1])
    增
    删
    换

如上所视,一共四种情况:

if(word1[i-1] == word23[j-1])说明不需要任何操作,递推公式:dp[i] [j] = dp[i-1] [j-1]

if(word1[i-1] !=word2[j-1]):

(1) word1删除一个元素,那么就是以下标i-2为结尾的word1与j-1为结尾的word2的最近编辑距离再加上一个操作。

dp[i] [j] = dp[i-1] [j] + 1

(2)word2删除一个元素,那么就是以下标i-1为结尾的word1与j-2为结尾的word2的最近编辑距离在加上一个操作。

dp[i] [j] =dp[i] [j-1] + 1

(3)替换元素,word1替换word1[i-1],使其与word2[j-1]相同。

dp[i] [j] =dp[i-1] [j-1] +1

综上取最小得递推公式:dp[i] [j] = min(min(dp[i-1] [j-1],dp[i-1] [j]),dp[i] [j-1]) + 1;

3.dp数组如何初始化

dp[i] [j]:表示以下标i-1为结尾的字符串word1和以下标j-1为结尾的字符串成word2,最近的编辑距离为dp[i] [j].

dp[i] [0]:以下标i-1为结尾的字符串word1和空字符串word2,最近编辑距离为dp[i] [0].

dp[i] [0]表示对word1里的元素全部做删除操作,dp[i] [0] = i;

同理:

dp[0] [j] = j;

for(int i = 0 ; i<= word1.size(); i++) dp[i] [0] = i;
for(int j = 0; j <=word2.size(); j++) dp[0] [j] = j;

4.确定遍历顺序

从上到下,从左到右。

5.举例推导dp数组

算法学习day56

2.3 代码

class Solution {
public:
    int minDistance(string word1, string word2) {
        // 创建一个二维数组来存储最小编辑距离
        // dp[i][j]表示将word1的前i个字符转换成word2的前j个字符所需的最小编辑距离
        vector<vector<int>> dp(word1.size() + 1, vector<int>(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;
        
        // 计算dp数组中的其他值
        for (int i = 1; i <= word1.size(); i++) {
            for (int j = 1; j <= word2.size(); j++) {
                // 如果word1的第i个字符等于word2的第j个字符
                // 则不需要进行任何操作,编辑距离等于dp[i-1][j-1]
                if (word1[i - 1] == word2[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1];
                }
                // 如果word1的第i个字符不等于word2的第j个字符
                // 则有三种操作:插入、删除、替换
                // 插入:dp[i][j-1]表示将word1的前i个字符转换成word2的前j-1个字符的最小编辑距离
                // 删除:dp[i-1][j]表示将word1的前i-1个字符转换成word2的前j个字符的最小编辑距离
                // 替换:dp[i-1][j-1]表示将word1的前i-1个字符转换成word2的前j-1个字符的最小编辑距离
                // 由于需要对word1进行操作,因此操作数需要加1
                else {
                    dp[i][j] = min(min(dp[i-1][j-1],dp[i-1][j]),dp[i][j-1]) + 1;
                }
            }
        }
        // 返回将word1的所有字符转换成word2的所有字符所需的最小编辑距离
        return dp[word1.size()][word2.size()];
    }
};

3.参考资料

[代码随想录]文章来源地址https://www.toymoban.com/news/detail-422437.html

到了这里,关于算法学习day56的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 代码随想录打卡第56天|583. 两个字符串的删除操作;72. 编辑距离

    583. 两个字符串的删除操作 关键点1:dp数组的含义 dp[i][j],使得以i-1为结尾word1 和 以j-1为结尾的word2 相同所需的最小步数; 关键点2:递归公式的推导 if(nums1[i-1] == nums2[j-1]),则i和j同时移动,所以为i-1,j-1;dp[i][j] = dp[i-1][j-1];由于不需要进行删除操作,所以不需要加1 如果不相

    2023年04月19日
    浏览(51)
  • [力扣 Hot100]Day9 找到字符串中所有字母异位词

    给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。 异位词指由相同字母重排列形成的字符串(包括相同的字符串)。 出处 跟昨天的思路类似,也是两个指针构成滑动窗口,窗口大小固定为p的长度。将p的字符存到

    2024年01月19日
    浏览(47)
  • 【算法详解】力扣415.字符串相加

    力扣链接:力扣415.字符串相加 给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和并同样以字符串形式返回。 你不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。 示例 1: 输入:num1 = “11”, num2 = “123” 输出:

    2024年01月22日
    浏览(44)
  • 算法学习——LeetCode力扣补充篇11(64. 最小路径和、48. 旋转图像 、169. 多数元素、394. 字符串解码、240. 搜索二维矩阵 II )

    64. 最小路径和 - 力扣(LeetCode) 描述 给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。 说明:每次只能向下或者向右移动一步。 示例 示例 1: 输入:grid = [[1,3,1],[1,5,1],[4,2,1]] 输出:7 解释:因为路径 1→3→1→

    2024年04月23日
    浏览(38)
  • 【每日挠头算法题(2)】压缩字符串|仅执行一次字符串交换能否使两个字符串相等

    点我直达~ 使用双指针法 大致过程如下: 使用双指针,分别读(read),写(write)指针,读指针不断向后走,当read指针走到最后位置处时,或read和read的下一个位置与当前位置不相等时,说明该read指针走到了某一串相同子串的最后位置处。 此时write指针开始记录具体的字符

    2024年02月08日
    浏览(53)
  • 算法刷题|583.两个字符串的删除操作、72.编辑距离

    题目:给定两个单词 word1 和 word2 ,返回使得 word1 和 word2 相同所需的最小步数。 每步 可以删除任意一个字符串中的一个字符。 dp[i][j] 表示以i-1结尾的word1子序列和以j-1结尾word2变成相同所需要的最小的步数为dp[i][j] 递推公式:分两种情况,word1.charAt(i-1) 和 word2.charAt(j-1)是否

    2024年02月08日
    浏览(47)
  • 力扣精选算法100题——找到字符串中所有字母异位词(滑动窗口专题)

    本题链接👉找到字符串中所有字母异位词 给定2个字符串s和p,找到s中所有p的变位词的字串,就是p是\\\"abc\\\",在s串中找到与p串相等的字串,可以位置不同,但是字母必须相同,比如”bca\\\",\\\"bac\\\"等,都是可以被称之为变位词。最终返回与p串字母相等但排列不同的字符串的初始索引

    2024年01月19日
    浏览(67)
  • 【算法】力扣【动态规划,LCS】1312. 让字符串成为回文串的最少插入次数

    1312. 让字符串成为回文串的最少插入次数 本文探讨的是力扣(LeetCode)上的第1312题:让字符串成为回文串的最少插入次数。这是一道属于动态规划类别下的困难题目,通常以回文串相关的操作来衡量算法的优化和执行效率。 问题的核心是给定一个字符串 s ,你可以在任意位

    2024年01月23日
    浏览(51)
  • 每日OJ题_算法_滑动窗口⑥_力扣438. 找到字符串中所有字母异位词

    目录 力扣438. 找到字符串中所有字母异位词 解析及代码1 解析及代码2 438. 找到字符串中所有字母异位词 - 力扣(LeetCode) 难度 中等 给定两个字符串  s  和  p ,找到  s   中所有  p   的  异位词  的子串,返回这些子串的起始索引。不考虑答案输出的顺序。 异位词  指由

    2024年01月24日
    浏览(48)
  • 【算法思考记录】动态规划入门!力扣2606. 找到最大开销的子字符串【Python3、动态规划】

    原题链接 动态规划(Dynamic Programming,简称 DP)是一种通过将原问题分解为相互重叠的子问题并只解决一次的方法来解决问题的算法优化技术。动态规划通常用于优化递归问题,通过存储子问题的解来避免重复计算,从而显著提高算法的效率。 动态规划的基本思想是将原问题

    2024年02月03日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包