72. 编辑距离

题目描述

给了两个单词word1和word2,问如果将word1转化为word2需要最少操作数?
可以怎么操作?插入字符,删除字符,替换字符

f1-动态规划-自底向上

基本分析

  1. 先明确可能的操作有几种?6种
  2. 以上6种有没有等价的,可以减少思考维度?有等价的,最后剩3种,word1增加,word1删除,word1修改
  3. 怎么定义状态?比较常见,定义为f[i][j]表示word1的前i个字符修改为word2的前j个字符的最少,因为考虑有0,0的情况,比字符长度多定义一位
  4. 考虑怎么转移?(1)分析第i位个第j位的关系,相同则可用f[i-1][j-1]转移;(2)不相同则在3个操作(删、增加、改)中取最小
  5. 对某个词是0的情况怎么进行边界处理?区分word1和word2是0的情况。(1)word1是0,锁定f[i]是0, 需要在列的维度上逐个字符去加;(2)word2是0,锁定f[j]是0,需要在行的维度上逐个去加

代码

class Solution:
def minDistance(self, word1: str, word2: str) -> int:
m, n = len(word1), len(word2)
f = [[0]*(n+1) for _ in range(m+1)]
# 预处理都是0的情况
f[0][0] = 0
# word2是0的情况,对应word1删除
for i in range(1, m+1):
f[i][0] = f[i-1][0] + 1
# word1是0的情况,对应word1增加
for j in range(1, n+1):
f[0][j] = f[0][j-1] + 1
# 其他情况,取3种可能最小
for i in range(1, m+1):
for j in range(1, n+1):
if word1[i-1] == word2[j-1]:
f[i][j] = f[i-1][j-1]
else:
f[i][j] = min(f[i-1][j-1], f[i][j-1], f[i-1][j]) + 1
return f[-1][-1]

复杂度

时间:O(mn)
空间:O(mn

总结

涉及这种2个字符串匹配的,考虑最少是两个维度,看有没有可能前i去满足前j
这里操作比较多,需要考虑有没有可能等价,这里把6转化成了3
这里的操作针对的是前i个前j,删除、增加、修改并没有限定位置
在转移的时候,根据末尾做了分类,相同简单,不同是3个的最小+1
定义状态的时候考虑要不要多定义一位?前0位在dp里面是有意义的,所以多定义了一位,在写末尾判断的时候,需要注意索引是第几位-1
对首行和首列的边界条件,可以先预处理了,这样一般情况的dp转移不用考虑太多边界



f2-状态压缩+自顶向下

基本分析

其他同上,这里考虑怎么用记忆化搜索实现

  1. 和dp的区别?(1)两个的方向不一样,dp是00时候知道结果,搜索是终点知道结果(某一个达到长度);(2)传递时候已知的方向不一样,一个前一个后
  2. 怎么写搜索?(1)参数:处理到的索引,从0开始;(2)结束情况:某一个单词达到了长度,剩余就能口算了,特别的,这里可以考虑边界上的情况;(2)转移:某位等和不等两种情况;(3)返回:最少次数

代码

class Solution:
def minDistance(self, word1: str, word2: str) -> int:
m, n = len(word1), len(word2)
@cache
def helper(i, j):
# 达到了word1的长度:
if i == m:
return n-j
# 达到了word2的长度
if j == n:
return m-i
if word1[i] == word2[j]:
return helper(i+1, j+1)
else:
ins = helper(i+1, j) + 1
dele = helper(i, j+1) + 1
rep = helper(i+1, j+1) + 1
return min(ins, dele, rep)
return helper(0, 0)

复杂度

时间:O(mn)
空间:O(mn)

总结

需要注意两者方向上的差别,导致在已知状态+递归方向上的区别
另外判定索引和单词长度的写法,避免了额外边界的讨论

posted @   zhangk1988  阅读(35)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示