题目
- 编辑距离
题目描述
给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数 。
你可以对一个单词进行如下三种操作:
插入一个字符 删除一个字符 替换一个字符
示例
示例一
输入:word1 = "horse", word2 = "ros"
输出:3
解释:
horse -> rorse (将 'h' 替换为 'r')
rorse -> rose (删除 'r')
rose -> ros (删除 'e')
示例二
输入:word1 = "intention", word2 = "execution"
输出:5
解释:
intention -> inention (删除 't')
inention -> enention (将 'i' 替换为 'e')
enention -> exention (将 'n' 替换为 'x')
exention -> exection (将 'n' 替换为 'c')
exection -> execution (插入 'u')
思路
动态规划问题,使用递归方式解决
1、明确base case
当一个字符串已经全部扫描完的情况,则直接累加另一个字符串剩余的长度
2、状态转移
两个字符串相等情况,则直接跳过
否则求插入/删除/替换中最小的方式
3、使用备忘录解决重复子问题
代码
package leetcode
import (
"log"
"fmt"
)
// minDistance
// 72. 编辑距离
// 使用递归方式解决动态规划问题
func minDistance(word1 string, word2 string) int {
// 备忘录
memorandum := map[string]int{}
var dp func(i, j int) int
dp = func(i, j int) (rs int) {
// TODO 验证
defer func() {
// log.Println(i, j, rs)
}()
// 备忘录解决重叠子问题
key := fmt.Sprintf("%d%d", i, j)
if data, ok := memorandum[key]; ok {
log.Println(key)
return data
}
// base case
// 当一个字符串已经全部扫描完的情况,则直接累加另一个字符串剩余的长度
if i == -1 {
rs = j + 1
return
}
if j == -1 {
rs = i + 1
return
}
// 状态转移
// 两个字符串相等情况,则直接跳过
if word1[i] == word2[j] {
rs = dp(i-1, j-1)
memorandum[key] = rs
return
}
// 插入/删除/替换
rs = min((dp(i, j-1) + 1), (dp(i-1, j) + 1), (dp(i-1, j-1) + 1))
memorandum[key] = rs
return
}
return dp(len(word1)-1, len(word2)-1)
}
// min
// 求最小值
func min(a, b, c int) int {
minNums := a
if b < minNums {
minNums = b
}
if c < minNums {
minNums = c
}
return minNums
}
// minDistanceV
// 编辑距离
// 使用DP table
func minDistanceV(word1 string, word2 string) int {
m := len(word1)
n := len(word2)
// 创建DP数组存储切片
dp := createSlice(m+1, n+1)
// base case
for i := 1; i <= m; i++ {
dp[i][0] = i
}
for i := 1; i <= n; i++ {
dp[0][i] = i
}
// 自底向上求解
for i := 1 ;i <=m; i++ {
for j := 1; j <= n; j ++ {
if word1[i-1] == word2[j-1] {
dp[i][j] = dp[i-1][j-1]
}else{
dp[i][j] = min(dp[i-1][j]+1,dp[i][j-1]+1,dp[i-1][j-1]+1)
}
}
}
log.Println(dp)
return dp[m][n]
}
// createSlice
// 创建二维切片
func createSlice(m, n int) [][]int{
data := make([][]int, m)
for key:= range data{
data[key] = make([]int, n)
}
return data
}
参考
来源:力扣(LeetCode)
链接:leetcode-cn.com/problems/ed…
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。