【动态规划】LeetCode 583. 两个字符串的删除操作 Java

news2025/1/9 2:14:31

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

在这里插入图片描述

我的代码,错误代码,只考虑到了字母出现的次数,没有考虑到两个字符串中字母出现的顺序

class Solution {
    public int minDistance(String word1, String word2) {
        int[] arr1 = new int[26];
        int[] arr2 = new int[26];
        for (char word : word1.toCharArray()) {
            arr1[word - 'a']++;
        }
        for (char word : word2.toCharArray()) {
            arr2[word - 'a']++;
        }
        int cnt = 0;
        for (int i = 0; i < 26; i++) {
            cnt += Math.abs(arr1[i] - arr2[i]);
        }
        return cnt;
    }
}

在这里插入图片描述
方法一,计算最长公共子序列

给定两个字符串word1和word2,分别删除若干字符之后使得两个字符串相同,则剩下的字符为两个字符串的公共子序列。为了使删除操作的次数少,剩下的字符应尽可能多。当剩下的字符为两个字符串的最长公共子序列时,删除的操作的次数最少。因此,可以计算两个字符串的最长公共子序列的长度,然后分别计算两个字符串的长度和最长公共子序列的长度之差,即为两个字符串分别需要删除的字符数,两个字符串各自需要删除的字符数之和即为最少的删除操作的总次数。

由这一题,引出LeetCode 1143 最长公共子序列

先看1143最长公共子序列的题解,然后再来看这题,代码几乎完全都不用变。

class Solution {
    public int minDistance(String word1, String word2) {
        return word1.length() + word2.length() - 2 * longestCommonSubsequence(word1, word2);
    }

    public int longestCommonSubsequence(String text1, String text2) {
        int n = text1.length();
        int m = text2.length();
        int[][] dp = new int[n + 1][m + 1];
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if (text1.charAt(i - 1) == text2.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }
        return dp[n][m];
    }
}

复杂度分析:

  • 时间复杂度:O(mn),其中m和n分别是字符串word1和字符串word2的长度。二维数组dp有m+1行和n+1列,需要对dp中的每个元素进行计算
  • 空间复杂度:O(mn),其中m和n分别是字符串word1和word2的长度。创建了m+1行和n+1列的二维数组dp。

方法二,动态规划

直接使用动态规划计算最少删除操作次数,不需要计算最长公共子序列的长度。

假设字符串text1和text2的长度分别为m和n,创建m+1行和n+1列的二维数组dp,其中dp[i][j]表示使text1[0:i]和text2[0:j]相同的最少删除操作次数。

上述表示中,text1[0:i]表示text1的长度为i的前缀,text2[0:j]表示text2的长度为j的前缀。

考虑动态规划的边界情况:

  • 当i=0时,text1[0:i]为空,空字符串和任何字符串要变成相同,只有将另一个字符串的字符全部删除,因此,对任意0<=j<=n,dp[0][j]=j
  • 当j=0时,text2[0:j]为空,同理可得,对任意0<=i<=m,有dp[i][0]=i

当i>0 且 j>0时,考虑dp[i][j]的计算:

  • 当text1[i-1]=text2[j-1]时,将这两个相同的字符称为公共字符,考虑使text1[0:i-1]和text2[0:j-1]相同的最少删除操作次数,再增加一个公共字符之后,最少删除操作次数不变,因此,dp[i][j]=dp[i-1][j-1]。
  • 当text1[i-1]!=text2[j-1]时,考虑以下两项:
    • 使text1[0:i-1]和text2[0:j]相同的最少删除操作次数,加上删除word[i-1]的1次操作
    • 使text1[0:i]和text2[0:j-1]相同的最少删除操作次数,加上删除word[j-1]的1次操作

要得到使得text1[0:i]和text2[0:j]相同的最少删除操作次数,应取两项中较小的一项,因此,dp[i][j] = min(dp[i-1][j],dp[i][j-1])+1

由此可以得到如下状态转移方程

在这里插入图片描述

class Solution {
    public int minDistance(String word1, String word2) {
        int n = word1.length();
        int m = word2.length();
        int[][] dp = new int[n + 1][m + 1];
        for (int i = 0; i <= n; i++) {
            dp[i][0] = i;
        }
        for (int j = 0; j <= m; j++) {
            dp[0][j] = j;
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1];
                } else {
                    dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + 1;
                }
            }
        }
        return dp[n][m];
    }

}

复杂度分析:

  • 时间复杂度:O(mn),其中m和n分别是字符串word1和word2的长度。二维数组dp有m+1行和n+1列,需要对dp中的每个元素进行计算
  • 空间复杂度:O(mn),其中m和n分别是字符串word1和word2的长度。创建了m+1行和n+1列的二维数组dp
    在这里插入图片描述

1143. 最长公共子序列

在这里插入图片描述
最长公共子序列问题是典型的二维动态规划问题。

假设字符串text1和text2的长度分别为m和n,创建m+1行和n+1列的二维数组dp,其中dp[i][j]表示text1[0:i]和text2[0:j]的最长公共子序列的长度。

上述表示中,text1[0:i]表示text1的长度为i的前缀,text2[0:j]表示text2的长度为j的前缀。

考虑动态规划的边界情况:

  • 当i=0时,text1[0:i]为空,空字符串和任何字符串的最长公共子序列的长度都是0,因此,对任意0<=j<=n,dp[0][j]=0
  • 当j=0时,text2[0:j]为空,同理可得,对任意0<=i<=m,有dp[i][0]=0

因此,动态规划的边界情况是:当i=0或j=0时,dp[i][j] = 0

当i>0 且 j>0时,考虑dp[i][j]的计算:

  • 当text1[i-1]=text2[j-1]时,将这两个相同的字符称为公共字符,考虑text1[0:i-1]和text2[0:j-1]的最长公共子序列,再增加一个字符(即公共字符)即可得到text1[0:i]和text2[0:j]的最长公共子序列,因此,dp[i][j]=dp[i-1][j-1]+1。
  • 当text1[i-1]!=text2[j-1]时,考虑以下两项:
    • text1[0:i-1]和text2[0:j]的最长公共子序列
    • text1[0:i]和text2[0:j-1]的最长公共子序列

要得到text1[0:i]和text2[0:j]的最长公共子序列,应取两项中长度较大的一项,因此,dp[i][j] = max(dp[i-1][j],dp[i][j-1])

由此可以得到如下状态转移方程
在这里插入图片描述

class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
        int n = text1.length();
        int m = text2.length();
        int[][] dp = new int[n + 1][m + 1];
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if (text1.charAt(i - 1) == text2.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }
        return dp[n][m];
    }
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/704521.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Fiddler抓包工具笔记

一、简介 Fiddler代理相当于中介的角色 快捷键ShiftF5去缓存刷新 二、抓包 1. 设置过滤器 没有设置过滤器的话&#xff0c;会抓所有的包&#xff0c;非常乱会混淆 隐藏包含这些内容的URL 2. 快速定位到需要的包 点击&#xff1a;Webforms菜单 界面分析&#xff1a; …

SQlite3 编译

参考博客&#xff1a;https://blog.csdn.net/flowerspring/article/details/121268403 1.下载C源码以及def文件https://www.sqlite.org/download.html 2. 下载完成之后解压 sqlite-amalgamation获取C源码&#xff0c;解压sqlite-dll-win32-xx获取里面的def文件。 3.新建sqlite…

前端vue入门(纯代码)18

不管何时何地&#xff0c;永远保持热爱&#xff0c;永远积极向上&#xff01;&#xff01;&#xff01; 【20.尚硅谷GitHub搜索案例_vue-resource实现】 1.vue-resource vue-resource 是 vue 中一个用于发送请求的插件。 vue 发送请求推荐使用 axios &#xff0c;vue-resourc…

2023上半年软考系统分析师科目一整理-23

2023上半年软考系统分析师科目一整理-23 对于如下所示的序列图所描述的场景&#xff0c;最适合于采用的设计模式是&#xff08;30&#xff09;&#xff1b;该模式适用的场合是&#xff08;31&#xff09;。 A&#xff0e;Visitor B&#xff0e;Strategy C&#xff0e;Observe…

TI AM64x工业核心板规格书(双核ARM Cortex-A53 + 单/四核Cortex-R5F + 单核Cortex-M4F,主频1GHz)

1 核心板简介 创龙科技SOM-TL64x是一款基于TI Sitara系列AM64x双核ARM Cortex-A53 单/四核Cortex-R5F 单核Cortex-M4F设计的多核工业级核心板&#xff0c;通过工业级B2B连接器引出5x TSN Ethernet、9x UART、2x CAN-FD、GPMC、PCIe/USB 3.1等接口。核心板经过专业的PCB Layo…

【C++练习】string:字符串题型训练(5道编程题)

【C练习】string:字符串题型训练 Ⅰ.字符串中的第一个唯一字符Ⅱ.字符串最后一个单词的长度Ⅲ.把字符串转换成整数Ⅳ.字符串相加Ⅴ.反转字符串 Ⅰ.字符串中的第一个唯一字符 解题思路&#xff1a; 第一种方法&#xff1a; 两次遍历 1.第一次遍历&#xff0c;将每个字符出现的次…

【HTTP 协议2】如何构造 HTTP 请求

文章目录 前言一、地址栏输入二、HTML 特殊标签三、form 表单四、ajax总结 前言 各位读者好, 我是小陈, 这是我的个人主页, 希望我的专栏能够帮助到你: &#x1f4d5; JavaSE基础: 基础语法, 类和对象, 封装继承多态, 接口, 综合小练习图书管理系统等 &#x1f4d7; Java数据结…

【Echarts】配置项归纳

【Echarts】配置项归纳 一、title二、legend三、grid四、xAxis/yAxis五、polar六、radiusAxis七、angleAxis八、radar九、dataZoom1. 内置型数据区域缩放组件2. 滑动条型数据区域缩放组件3. 框选型数据区域缩放组件 十、tooltip十一、axisPointer十二、toolbox十三、brush十四、…

不定长图文模型训练

文章目录 生成数据集模型选择计算均值和标准差训练代码测试集测试 生成数据集 import os import random from PIL import Image, ImageDraw, ImageFont, ImageFilter from io import BytesIO import timedef main():_first_num random.randint(1, 1000)_code_style [加, 减,…

【uniapp开发小程序】实现粘贴一段文字后,自动识别到姓名/手机号/收货地址

一、需求 在uni-app中开发小程序&#xff0c;实现粘贴一段文字后自动识别到手机号&#xff0c;并将手机号前面的内容作为姓名&#xff0c;手机号后面的内容作为收货地址&#xff0c;并去除其中的特殊字符和前缀标识。 实现效果&#xff1a; 二、实现方式&#xff1a; <…

【vue】vue.js中引入组件

目录 ⭐️一、点击按钮1弹出弹窗⭐️二、vue.js引入组件具体步骤1、创建自定义组件的文件夹&#xff08;以弹窗组件为例&#xff09;2、在index.vue中引入keyProductsTip.vue模块3、在index.vue中引入组件4、在index.vue中使用组件&#xff0c;点击按钮打开弹窗5、index.vue中的…

高级web前端开发工程师的主要职责模板(合集)

高级web前端开发工程师的主要职责模板1 职责&#xff1a; 1、web端页面的制作、开发和优化; 2、编写静态和动态页面和交互、特效等功能的脚本程序; 3、开发基于HTML5技术的可灵活定制、可扩展的前端UI组件; 4、优化前端架构&#xff0c;提高系统的灵活性和可扩展性; 5、开…

【AUTOSAR】BMS开发实际项目讲解(二十六)----电池管理系统低压上下电功能

低压上下电功能 关联的系统需求 Sys_Req_3101、Sys_Req_3102、Sys_Req_3103、Sys_Req_3104; 功能实现描述 低压上电管理 ID Description ASIL Ref. LVM-101 当系统检测到如下任一信号有效时&#xff1a; 整车CAN、ACC、IGN、CC、CP唤醒、一路预留硬线唤醒系统应…

Java安全——存取控制器

Java安全 存取控制器 Java安全中的存取控制器是一种技术&#xff0c;用于控制访问应用程序中的资源。它的基本思想是允许或拒绝特定用户对系统资源的访问。存取控制器包括四个关键部分: 主体(subject), 权限(permission), 对象(object)和存取控制策略(access control policy)。…

【vue3】学生管理案例

此案例可以分为4个部分&#xff1a; 渲染学生列表新增学生删除学生搜索学生 涉及的知识点主要为v-model双向绑定数据。 页面&#xff1a; <div id"main"><table><tr><td>学号</td><td>姓名</td><td>新增时间<…

121.【ElasticSearch伪京东搜索】

模仿京东搜索 (一)、搭建环境0.启动ElasticSearch和head和kblian(1).启动EslaticSearch (9200)(2).启动Es-head (9101)(3).启动 Kibana (5602) 1.项目依赖2.启动测试 (二)、爬虫1.数据从哪里获取2.导入爬虫的依赖3.编写爬虫工具类(1).实体类(2).工具类编写 4.导入配置类 (三)、…

Selenium系列(四) - 详细解读鼠标操作

引入HTML页面 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>测试笔记</title> </head> <body><a>用户名:</a> <input id"username" class"userna…

航空枢纽联通亚欧,开放合作互利共赢 —乌鲁木齐国际航空枢纽建设论坛将于7月6日召开

为创新开放型经济体制&#xff0c;加快建设对外开放大通道&#xff0c;更好利用国际国内两个市场、两种资源&#xff0c;积极服务和融入双循环新发展格局&#xff0c;促进经济高质量发展&#xff0c;2023年7月6日-7日&#xff0c;以“航空枢纽联通亚欧&#xff0c;开放合作互利…

基于matlab使用单眼摄像机图像数据构建室内环境地图并估计摄像机的轨迹(附源码)

一、前言 视觉同步定位和映射 &#xff08;vSLAM&#xff09; 是指计算摄像机相对于周围环境的位置和方向&#xff0c;同时映射环境的过程。该过程仅使用来自相机的视觉输入。vSLAM 的应用包括增强现实、机器人和自动驾驶。 此示例演示如何处理来自单眼摄像机的图像数据&…

从小白到大神之路之学习运维第50天---第三阶段----MMM高可用集群数据库的安装部署

第三阶段基础 时 间&#xff1a;2023年6月30日 参加人&#xff1a;全班人员 内 容&#xff1a; Mysql---MMM高可用集群架构 目录 一、MMM介绍 二、MMM工作原理 三、MMM安装部署 环境配置&#xff1a;&#xff08;所有主机配置&#xff09; 1、主机信息 ​编辑 2、…