编辑距离问题

简介: 编辑距离问题

前言

给你两个单词 word1 和 word2, 请返回将 word1 转换成 word2 所使用的最少操作数 。

你可以对一个单词进行如下三种操作:

插入一个字符
删除一个字符
替换一个字符

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/edit-distance
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

进阶,每种操作都会有相应的代价

一、动态规划

这是样本对应模型,一个样本做行,一个样本做列
dpi:str1前缀取前i个字符,编辑成str2前缀取j个字符最少代价是多少
如果这张表我们能够顺利求完,最右下角返回就是答案,
第0行str1空串编辑为str2,只能添加
第0列str2编辑成str1空串,只能删除

可能性1:
str1的前i-1个字符变成str2的前j个字符,即删掉str1的最后一个字符

可能性2:
str1的整体先变成str2的前j-1个字符,最后再加上str2的最后一个字符

可能性3:
str1, str2两个字符串最后一个字符串相等str1前面i-1个字符变成str2前面j-1个字符,最后一个字符保留

可能性4:
两个字符串最后一个字符串不相等,str1前面i-1个字符变成str2前面j-1个字符,最后一个字符串做替换

二、代码

    public static int minCost1(String s1, String s2, int ic, int dc, int rc) {
        if (s1 == null || s2 == null) {
            return 0;
        }
        char[] str1 = s1.toCharArray();
        char[] str2 = s2.toCharArray();
        int N = str1.length + 1;
        int M = str2.length + 1;
        int[][] dp = new int[N][M];
        // dp[0][0] = 0
        for (int i = 1; i < N; i++) {
            dp[i][0] = dc * i;
        }
        for (int j = 1; j < M; j++) {
            dp[0][j] = ic * j;
        }
        for (int i = 1; i < N; i++) {
            for (int j = 1; j < M; j++) {
                dp[i][j] = dp[i - 1][j - 1] + (str1[i - 1] == str2[j - 1] ? 0 : rc);
                dp[i][j] = Math.min(dp[i][j], dp[i][j - 1] + ic);
                dp[i][j] = Math.min(dp[i][j], dp[i - 1][j] + dc);
            }
        }
        return dp[N - 1][M - 1];
    }

空间压缩

我们发现dpi依赖左边,上边,左上的位置,因此可以做空间压缩

    public static int minCost2(String str1, String str2, int ic, int dc, int rc) {
        if (str1 == null || str2 == null) {
            return 0;
        }
        char[] chs1 = str1.toCharArray();
        char[] chs2 = str2.toCharArray();
        char[] longs = chs1.length >= chs2.length ? chs1 : chs2;
        char[] shorts = chs1.length < chs2.length ? chs1 : chs2;
        if (chs1.length < chs2.length) {
            int tmp = ic;
            ic = dc;
            dc = tmp;
        }
        int[] dp = new int[shorts.length + 1];
        for (int i = 1; i <= shorts.length; i++) {
            dp[i] = ic * i;
        }
        for (int i = 1; i <= longs.length; i++) {
            int pre = dp[0];
            dp[0] = dc * i;
            for (int j = 1; j <= shorts.length; j++) {
                int tmp = dp[j];
                if (longs[i - 1] == shorts[j - 1]) {
                    dp[j] = pre;
                } else {
                    dp[j] = pre + rc;
                }
                dp[j] = Math.min(dp[j], dp[j - 1] + ic);
                dp[j] = Math.min(dp[j], tmp + dc);
                pre = tmp;
            }
        }
        return dp[shorts.length];
    }

总结

对于两个字符串的相互变化问题,可以考虑动态规划中的样本对应模型

相关文章
|
9月前
|
C语言
【C语言程序设计——循环程序设计】统计海军鸣放礼炮声数量(头歌实践教学平台习题)【合集】
有A、B、C三艘军舰同时开始鸣放礼炮各21响。已知A舰每隔5秒1次,B舰每隔6秒放1次,C舰每隔7秒放1次。编程计算观众总共听到几次礼炮声。根据提示,在右侧编辑器Begin--End之间的区域内补充必要的代码。开始你的任务吧,祝你成功!
180 13
|
12月前
|
传感器 边缘计算 自动驾驶
|
SQL 数据采集 分布式计算
Dataphin
Dataphin 是一款基于数据中台思想打造的数据管理平台,它提供了数据建模、数据集成、数据质量、数据开发、数据服务等一系列数据管理功能,旨在帮助企业实现数据的有效管理、优化数据资产和提高数据价值。
720 0
|
Ubuntu Java Linux
使用阿里云服务器开我的世界基岩版服务器
想和好友玩我的世界手机版但是不在同一个局域网那么这是你们最好的选择,那就是自己动手开一个。
1075 0
使用阿里云服务器开我的世界基岩版服务器
|
机器学习/深度学习 缓存 分布式计算
|
数据采集 供应链 前端开发
业务数据双中台助力实现大型医药集团
业务数据双中台助力实现大型医药集团
442 0
|
存储 弹性计算 安全
阿里云服务器4核16G配置可选实例规格及最新价格和收费标准参考
阿里云4核16G服务器有通用型 g6、通用型 g7、内存型 r7p等20多种中实例规格可选,实例规格不同,收费标准与活动价格也不同,目前阿里云通用型g7和通用算力型u1实例4核16G云服务器有优惠,最低价仅需1710元1年,本文为大家介绍一下阿里云服务器4核16G配置可选实例规格和收费标准及最新活动报价,以供大家参考。
|
Linux 数据库 C语言
C语言可以应用在哪些领域?
在计算机编程语言中,C语言是用的最多的一种语言,也是目前最为热门的一种编程语言之一。例如嵌入式的C51单片机、ARM的CORTE-M3/4等系列芯片下编程,绝大多数情况下都是用C语言进行编程以及产品开发的。
|
XML 数据可视化 Java
史上最全的工作流引擎 Activiti 学习教程(值得收藏)(三)
史上最全的工作流引擎 Activiti 学习教程(值得收藏)(三)
史上最全的工作流引擎 Activiti 学习教程(值得收藏)(三)
|
JSON 缓存 小程序
支付宝小程序 API
本章我们将讲述支付宝小程序比较常用的几个 JSAPI,带你走进 JSAPI 的奇妙世界。
支付宝小程序 API