- 题目描述
给你两个单词 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')
提示:
0 <= word1.length, word2.length <= 500
word1 和 word2 由小写英文字母组成
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/edit-distance
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
-
思路
1、动态规划,难得是状态的定义比较跳跃
2、使用dp[i][j]定义状态,dp[i][j]表示word1的前i个字符转换为word2的前j个字符所使用的最少操作数
3、状态间的转换过程为前一步的3种操作(插入,删除,替换)所需的最少操作数在加上1就是当前的结果 -
代码
package main
import (
"fmt"
)
func minDistance(word1 string, word2 string) int {
var (
l1 = len(word1)
l2 = len(word2)
dp = make([][]int,l1)
)
//处理单词为空的情况
if l1 == 0 || l2 == 0 {
return l1 + l2
}
//初始化dp
for i:=0; i<l1; i++ {
t := make([]int,l2)
dp[i] = t
}
//初始化边界情况
ti := 1
for i:=0; i<l1; i++ {
if word1[i] == word2[0] {
ti = 0
}
dp[i][0] = i + ti
}
ti = 1
for i:=0; i<l2; i++ {
if word1[0] == word2[i] {
ti = 0
}
dp[0][i] = i + ti
}
//核心处理
for i:=1; i<l1; i++ {
for j:=1; j<l2; j++ {
if word1[i] == word2[j]{
dp[i][j] = dp[i-1][j-1]
}else {
dp[i][j] = min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1]) + 1
}
}
}
return dp[l1-1][l2-1]
}
//返回3个数中的最小值
func min(a int, b int, c int) int {
if a < b {
if a < c {
return a
}else{
return c
}
}else{
if b < c {
return b
}else{
return c
}
}
}
func main() {
word1 := "a"
word2 := "hha"
//word1 := "intention"
//word2 := "execution"
//word1 := "pneumonoultramicroscopicsilicovolcanoconiosis"
//word2 := "ultramicroscopically"
res := minDistance(word1,word2)
fmt.Println(res)
}