每日一题——编辑距离
编辑距离
- 参考资料
- 题目描述
- 示例
- 解题思路
- 动态规划(DP)方法
- 代码实现
- 复杂度分析
- 示例详解
- 示例1:`"nowcoder"` → `"new"`
- 示例2:`"intention"` → `"execution"`
- 总结与心得
参考资料
建议先参考下面一个视频和文档,然后再思考问题,不然很容易会被吓到。
——
https://programmercarl.com/0072.%E7%BC%96%E8%BE%91%E8%B7%9D%E7%A6%BB.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE

题目描述
给定两个字符串 str1 和 str2,计算将 str1 转换为 str2 所需的最小操作次数。每次操作可以执行以下三种操作之一:
- 插入一个字符
- 删除一个字符
- 修改一个字符
示例
- 示例1:
- 输入:
"nowcoder", "new" - 输出:
6 - 解释:修改 ‘o’ 为 ‘e’,删除后续5个字符
- 输入:
- 示例2:
- 输入:
"intention", "execution" - 输出:
5 - 解释:需要修改前5个字符
- 输入:
解题思路
动态规划(DP)方法
-
状态定义
dp[i][j]表示将str1的前i个字符转换为str2的前j个字符所需的最小操作次数
-
状态转移方程
- 当
str1[i-1] == str2[j-1]时:dp[i][j] = dp[i-1][j-1] - 否则,取三种操作的最小值加1:
- 修改操作:
dp[i-1][j-1] + 1 - 插入操作:
dp[i][j-1] + 1 - 删除操作:
dp[i-1][j] + 1
- 修改操作:
- 当
-
初始化
dp[i][0] = i:表示删除操作dp[0][j] = j:表示插入操作
代码实现
#include <string.h> // 引入字符串处理函数库,用于调用strlen等函数// 辅助函数:计算三个整数中的最小值
int min(int a, int b, int c) {// 使用三元运算符实现最小值计算// 首先比较a和b,取较小值,再与c比较,最终返回最小值return a < b ? (a < c ? a : c) : (b < c ? b : c);
}// 主函数:计算两个字符串之间的编辑距离
int editDistance(char* str1, char* str2) {// 获取两个字符串的长度int len1 = strlen(str1); // str1的长度int len2 = strlen(str2); // str2的长度// 处理空字符串情况// 如果str1为空,将str2的所有字符插入到str1中,需要len2次操作if (len1 == 0) return len2;// 如果str2为空,将str1的所有字符删除,需要len1次操作if (len2 == 0) return len1;// 创建动态规划表dp,大小为(len1+1)×(len2+1)// dp[i][j]表示str1的前i个字符转换为str2的前j个字符所需的最小操作数int dp[len1 + 1][len2 + 1];// 初始化动态规划表的第一行和第一列// dp[i][0]:将str1的前i个字符转换为空字符串,需要i次删除操作for (int i = 0; i <= len1; i++) dp[i][0] = i;// dp[0][j]:将空字符串转换为str2的前j个字符,需要j次插入操作for (int j = 0; j <= len2; j++) dp[0][j] = j;// 动态规划过程:填充dp表// 遍历str1和str2的每个字符for (int i = 1; i <= len1; i++) {for (int j = 1; j <= len2; j++) {// 如果当前字符相同,不需要额外操作,直接继承左上角的值if (str1[i - 1] == str2[j - 1]) {dp[i][j] = dp[i - 1][j - 1];} else {// 如果当前字符不同,选择三种操作的最小值 + 1// dp[i - 1][j - 1]:替换操作// dp[i][j - 1]:插入操作// dp[i - 1][j]:删除操作dp[i][j] = min(dp[i - 1][j - 1], dp[i][j - 1], dp[i - 1][j]) + 1;}}}// 返回最终的编辑距离,即dp表右下角的值return dp[len1][len2];
}
复杂度分析
- 时间复杂度:O(mn),其中m和n分别是两个字符串的长度
- 空间复杂度:O(mn),需要一个二维数组存储动态规划的状态
示例详解
示例1:"nowcoder" → "new"
- 对于第一个位置,两个字符串都是’n’,不需要操作
- 第二个位置,需要将’o’修改为’e’,操作数+1
- 接下来需要删除"wcoder"这5个字符,每个字符删除操作数+1
- 最终需要6次操作
示例2:"intention" → "execution"
- 两个字符串后缀"tion"相同,不需要操作
- 需要修改前5个字符,每个字符修改操作数+1
- 最终需要5次操作
总结与心得
这道题虽然看起来操作较多(增删改),但实际难度适中,比起IP地址字符串转换的题目要简单一些。关键在于理解动态规划的状态设计:
-
一开始可能会想直接用m×n的dp数组(去掉第一行第一列),但这样是不行的。因为如果两个字符串完全相同,结果应该是0,所以需要包含这种情况。
-
初始化很重要:第一行和第一列分别表示纯粹的删除和插入操作,这为后续的状态转移奠定了基础。
-
状态转移方程的设计体现了问题的本质:当字符相同时不需要操作,当字符不同时取三种操作的最小值。
相关文章:
每日一题——编辑距离
编辑距离 参考资料题目描述示例 解题思路动态规划(DP)方法 代码实现复杂度分析示例详解示例1:"nowcoder" → "new"示例2:"intention" → "execution" 总结与心得 参考资料 建议先参考下…...
TensorFlow项目GPU运行 安装步骤
以下是在 Linux 系统 下搭建完整 GPU 加速环境的详细流程(适配 CUDA 11.2 和 Python 3.9): 1. 前置检查 1.1 验证 NVIDIA 驱动 # 检查驱动版本(需 ≥ 450.80.02) nvidia-smi 输出示例: CUDA Version: 11.2…...
c++进阶———继承
1.引言 在一些大的项目中,我们可能要重复定义一些类,但是很麻烦,应该怎么办呢?举个简单的例子,我要做一个全校师生统计表,统计学号,教师编号,姓名,年龄,电话…...
FreeSwitch的mod_translate模块详细,附带场景案例及代码示例
mod_translate 模块详细介绍 mod_translate 是 FreeSWITCH 中的一个拨号计划应用程序模块,用于对电话号码或字符串进行格式转换和翻译。它可以根据预定义的规则对输入的内容进行匹配和转换,常用于号码格式化、路由选择、号码屏蔽等场景。 主要功能 号码…...
前端504错误分析
前端出现504错误(网关超时)通常是由于代理服务器未能及时从上游服务获取响应。以下是详细分析步骤和解决方案: 1. 确认错误来源 504含义:代理服务器(如Nginx、Apache)在等待后端服务响应时超时。常见架构:前端 → 代理服务器 → 后端服务,问题通常出在代理与后端之间。…...
在 .NET 8/9 中使用 AppUser 进行 JWT 令牌身份验证
文章目录 一、引言二、什么是 JSON Web 令牌?三、什么是 JSON Web 令牌结构?四、设置 JWT 令牌身份验证4.1 创建新的 .NET 8 Web API 项目4.2 安装所需的 NuGet 软件包4.3 创建 JWT 配置模型4.4 将 JWT 配置添加到您的 appsettings.json 中4.5 为 Config…...
基于python实现机器学习的心脏病预测系统
以下是一个基于 Python 实现的简单心脏病预测系统代码示例,我们将使用 Scikit - learn 库中的机器学习算法(这里以逻辑回归为例),并使用公开的心脏病数据集。 步骤: 数据加载与预处理:加载心脏病数据集&a…...
使用 NVM 随意切换 Node.js 版本
安装nvm https://github.com/coreybutler/nvm-windows/releases nvm安装详细教程(卸载旧的nodejs,安装nvm、node、npm、cnpm、yarn及环境变量配置)-CSDN博客 验证 NVM 是否安装成功-查看版本 nvm --version安装指定版本的 Node.js nvm i…...
【Prometheus】prometheus结合pushgateway实现脚本运行状态监控
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…...
SpringBoot 项目配置动态数据源
目录 一、前言二、操作1、引入依赖2、配置默认数据库 13、定义数据源实体和 Repository4、定义动态数据源5、配置数据源6、定义切换数据源注解7、定义切面类8、使用注解切换数据源 一、前言 通过切面注解方式根据不同业务动态切换数据库 二、操作 1、引入依赖 <dependen…...
CSS基本选择器
1. 通配选择器 作用:可以选中所有的 HTML 元素。 语法: * { 属性名: 属性值; } 举例: <!DOCTYPE html> <html lang"zh-cn"> <head><meta charset"UTF-8"><meta name"viewport" …...
idea-代码补全快捷键
文章目录 前言idea-代码补全快捷键1. 基本补全2. 类型匹配补全3. 后缀补全4. 代码补全 前言 如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。 而且听说点赞的人每天的运气都不会太差,…...
基于SpringBoot+vue粮油商城小程序系统
粮油商城小程序为用户提供方便快捷的在线购物体验,包括大米、面粉、食用油、调味品等各种粮油产品的选购,用户可以浏览商品详情、对比价格、下单支付等操作。同时,商城还提供优惠活动、积分兑换等福利,让用户享受到更多实惠和便利…...
挪车小程序挪车二维码php+uniapp
一款基于FastAdminThinkPHP开发的匿名通知车主挪车微信小程序,采用匿名通话的方式,用户只能在有效期内拨打车主电话,过期失效,从而保护车主和用户隐私。提供微信小程序端和服务端源码,支持私有化部署。 更新日志 V1.0…...
企业内部知识库:安全协作打造企业智慧运营基石
内容概要 作为企业智慧运营的核心载体,企业内部知识库通过结构化的信息聚合与动态化的知识流动,为组织提供了从数据沉淀到价值转化的系统性框架。其底层架构以权限管理为核心,依托数据加密技术构建多层级访问控制机制,确保敏感信…...
网络安全推荐的视频教程 网络安全系列
第一章 网络安全概述 1.2.1 网络安全概念P4 网络安全是指网络系统的硬件、软件及其系统中的数据受到保护,不因偶然的或恶意的原因而遭到破坏、更改、泄露,系统连续可靠正常地运行,网络服务不中断。 1.2.3 网络安全的种类P5 (1…...
麒麟管家全新升级,运维问题“一键修复”
麒麟管家是openKylin社区SystemManager SIG开发的一款面向社区用户,能倾听用户烦恼和诉求,也能提供便利途径、解决用户问题的系统管理类应用,可以为用户提供问题反馈、系统垃圾清理、电脑故障排查、硬件设备管理及系统小工具等一站式服务&…...
MVCC(多版本并发控制)机制讲解
MVCC(Multi-Version Concurrency Control,多版本并发控制)这是一个在数据库管理系统中非常重要的技术,尤其是在处理并发事务时。别担心,我会用简单易懂的方式来讲解,让你轻松掌握它的原理和作用。 1. 什么是…...
React 与 Vue 对比指南 - 上
React 与 Vue 对比指南 - 上 本文将展示如何在 React 和 Vue 中实现常见功能,从基础渲染到高级状态管理 Hello 分别使用 react 和 vue 写一个 Hello World! react export default () > {return <div>Hello World!</div>; }vue <…...
开源协议深度解析:理解MIT、GPL、Apache等常见许可证
目录 前言1. MIT协议:自由而宽松的开源许可1.1 MIT协议的主要特点1.2 MIT协议的适用场景 2. GPL协议:自由软件的捍卫者2.1 GPL协议的核心理念2.2 GPL协议的适用场景 3. Apache License 2.0:开源与专利保护的平衡3.1 Apache License 2.0的主要…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
