题解 | #编辑距离(一)#

编辑距离(一)

https://www.nowcoder.com/practice/6a1483b5be1547b1acd7940f867be0da

秒懂【编辑距离】!动态规划一步步拆解。

1.思路

当str1[i-1]==str[j-1] 时,不用编辑,因此dp[i-1][j-1]

当str1[i-1] != str[j-1] 时,需要编辑(删除、增加、或者修改选其中一个最小的值),因此dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1

alt

如果文字描述的不太清楚,你可以参考视频的详细讲解B站@好易学数据结构

2.代码

2.1 Python代码

#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param str1 string字符串
# @param str2 string字符串
# @return int整型
#
class Solution:
    def editDistance(self, str1: str, str2: str) -> int:
        # write code here
        m = len(str1)
        n = len(str2)
        # 1. 定义状态.   dp[i][j]:字符串str1[0:i - 1] 与str2[0:j - 1] 的最少操作数
        dp = [[0] * (n + 1) for _ in range(m + 1)]
        # 2. 初始化边界条件: dp[i][0] = i str1增加或删除i个元素会变成str2(str2为空); dp[0][j] = j str2增加或删除j个元素会变成str1(str1为空)
        # 2.1 初始化第0行
        for j in range(n + 1):
            dp[0][j] = j
        # 2.2 初始化边界第0列
        for i in range(m + 1):
            dp[i][0] = i
        # 3.确定递推公式:
        for i in range(1, m + 1):
            for j in range(1, n + 1):
                if str1[i - 1] == str2[j - 1]:
                    dp[i][j] = dp[i - 1][j - 1]  # 若是字符相同,此处不用编辑,直接等于前一个的距离
                else:
                    # 删、增、修改中获取最小再加上1(删、增、修改对应于1次编辑)
                    dp[i][j] = min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1
        # 4. 输出结果
        return dp[m][n]

2.2 Java代码

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param str1 string字符串
     * @param str2 string字符串
     * @return int整型
     */
    public int editDistance (String str1, String str2) {
        // write code here
        int m = str1.length();
        int n = str2.length();
        // 1.定义状态.   dp[i][j]:字符串str1[0:i-1]与str2[0:j-1]的最少操作数
        int[][] dp = new int[m + 1][n + 1];
        // 2.初始化边界条件:dp[i][0] = i str1增加或删除i个元素会变成str2(str2为空); dp[0][j] = j str2增加或删除j个元素会变成str1(str1为空)
        // 2.1初始化第0行
        for (int j = 0; j <= n; j++) {
            dp[0][j] = j;
        }
        // 2.2初始化边界第0列
        for (int i = 0; i <= m; i++) {
            dp[i][0] = i;
        }
        // 3.确定递推公式:
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
                    //若是字符相同,此处不用编辑,直接等于前一个的距离
                    dp[i][j] = dp[i - 1][j - 1];
                } else {
                    //删、增、修改中获取最小再加上1(删、增、修改对应于1次编辑)
                    dp[i][j] = min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1;
                }
            }
        }
        //4.输出结果
        return dp[m][n];
    }


    private int min(int a, int b, int c) {
        int res;
        if (a <= b && a <= c) {
            res = a;
        } else if (b <= a && b <= c) {
            res = b;
        } else {
            res = c;
        }
        return res;
    }
}

2.3 Go代码

package main


/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 *
 * @param str1 string字符串
 * @param str2 string字符串
 * @return int整型
 */
func editDistance(str1 string, str2 string) int {
	// write code here
	m := len(str1)
	n := len(str2)
	// 1.定义状态.	   dp[i][j]:字符串str1[0:i-1]与str2[0:j-1]的最少操作数
	dp := newArray(m+1, n+1)
	// 2.初始化边界条件:dp[i][0] = i str1增加或删除i个元素会变成str2(str2为空); dp[0][j] = j str2增加或删除j个元素会变成str1(str1为空)
	// 2.1初始化第0行
	for j := 0; j <= n; j++ {
		dp[0][j] = j
	}
	// 2.2初始化边界第0列
	for i := 0; i <= m; i++ {
		dp[i][0] = i
	}
	// 3.确定递推公式:
	for i := 1; i <= m; i++ {
		for j := 1; j <= n; j++ {
			if str1[i-1] == str2[j-1] {
				dp[i][j] = dp[i-1][j-1] //若是字符相同,此处不用编辑,直接等于前一个的距离
			} else {
				//删、增、修改中获取最小再加上1(删、增、修改对应于1次编辑)
				dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1
			}
		}
	}
	//4.输出结果
	return dp[m][n]
}

// 创建一个 m行n列的矩阵(二维数组)
func newArray(m int, n int) [][]int {
	arr := make([][]int, m)
	for i := 0; i < m; i++ {
		arr[i] = make([]int, n)
	}
	return arr
}
func min(a, b, c int) int {
	var res int
	if a <= b && a <= c {
		res = a
	} else if b <= a && b <= c {
		res = b
	} else {
		res = c
	}
	return res
}

如果上面的代码理解的不是很清楚,你可以参考视频的详细讲解B站@好易学数据结构

#秋招白月光##牛客创作赏金赛##笔试##笔试题目#
全部评论
点赞 回复 分享
发布于 2025-11-12 13:02 上海
秒懂了
点赞 回复 分享
发布于 2025-07-23 16:55 四川

相关推荐

2025-12-08 16:04
门头沟学院 Java
本人本科末9,今年大三。大一大二一直玩,什么都没学到,在大学混日子混了两年,每天不是在打农就是在steam。大三开学时一个和自己玩的好的同学去实习了,才发现自己白白浪费了两年的时间,如果真不冲一下就真去京东,阿里,美团送外卖了今年9月份开始学Java,一开始一直跟着黑马视频看,后面发现看视频效率太低了,时间根本不够,就开始主要看文档和看书了。这几个月一直在学,真的尽力了,希望暑期前能找一份好点的实习。我简历上面的项目大多没有指标,但是实际上我是真没多少时间去做项目,我基本主要是动手只做了外卖和天机,黑马点评和12306我都是只是看了项目。主要是自己的时间真的不多,但是这样子自己的代码能力确实比较差。而且自己也没有做过实际的工程,我顶多用jmeter测试一下接口tps啥的,比如使用Redis管道提升了一点性能,减少Redis交互,这种值得写上去吗?需不需要具体到某些数字求求各位佬给一些建议,看看简历怎么优化?项目介绍是不是不够详细?没有具体到业务方面。项目会不会提到大致实现原理导致面试官一看简历就知道怎么实现就没有问的欲望?专业技能一些字段是不是要加粗,是不是写太啰嗦了?有没有必要压缩内容变成一页?两页的话是不是都要把两页填地满满的。
给秋招一个交代:一页简历最好,网上做的项目放面试官眼里都是玩具,简历上不需要强调有什么难点,记住就行防止真的问。然后背八股,多投多面试就行
点赞 评论 收藏
分享
当年还在美团那个倒霉的&nbsp;Peppr&nbsp;团队工作时,我一直有个疑问:这群人每天到底在自嗨什么。每次开会一堆人围着一堆“看起来很高级”的文档转,模板统一、名词复杂、页数感人,每一页都在暗示一件事:“你不懂,是因为你不专业。”但现实是——代码照样写在&nbsp;💩&nbsp;山上,该出问题还是会出问题,这真的很逗,系统一出问题,文档的唯一作用就是证明:“我们当初确实认真写过文档。”所以本质区别到底是什么?是代码质量提升了,还是大家在精神层面完成了一次“工程师&nbsp;cosplay”?有句话说得好潮水退去才知道谁在裸泳。还记得当时的马哥、明哥(图&nbsp;1&nbsp;左)最爱反复强调一句话:“所有场景一定要想到。”、“这个场景为什么没考虑到?”不过他们这些话我是真的听进去了。不然我也不会在一年多前就说:这个项目活不过两年。顺带一提,那段时间还有个固定节目。每次下楼,总能听见我明哥在吐槽不同的人。我从他身后绕过去,经常能听到他一边抽烟一边说:“xx&nbsp;这小子太坑了,回头我一定要跟马哥说说。”于是深谙人情世故但真不会抽烟的我也会从口袋掏出一支低尼古丁含量的烟给自己点上,假意自己什么都没听到什么都不知道,只是来抽烟的。后来我才明白,这可能也是团队文化的一部分:问题永远在别人身上,而我们,永远在复盘里😂。
秋招白月光
点赞 评论 收藏
分享
评论
3
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务