时间复杂度:O(n²)
解题思路
很难想的一道动态规划题目。
对于官方的题解,我也只能是懂个大概,大致说来就是将操作分为三种,分别是对A增添字符、对B增添字符和修改A的字符,如下官方题解所述:
对于 A中插入一个字符,我是这么理解的:当经过a步的变换后,horse和ro已经变为相同的字符串(注意不是horse变为了ro,而是变为相同的字符串,具体是什么相同的字符串就不清楚了),但是此时我们只实现了让horse和ro相同,目标是让horse和ros相同,那我们就可以事先在A末尾增添一个s变为horses,这样s之前的horse字符串经过a步会和ro相同,最后的结果就是原相同的字符串后多了一个s,这样就可以理解为horse变成了和ros相同的字符串;
对于B的理解也大致同A,事先在ros末尾增添一个e变为rose,这样经过b步会变成horse;
修改A的字符,就是把horse的e修改为s,这样字符串变成了horss,末尾字符与ros的s相同,所以编辑距离为c+1;
根据以上的三种状态变化,便可得到状态转移方程,简单来讲就是如果两个字符串的末尾字符相同,那么dp[i][j]就是dp[i-1][j]+1、dp[i][j-1]+1和dp[i-1][j-1]的最小值;如果两个字符串末尾字符不相同,那么dp[i][j]就是dp[i-1][j]+1、dp[i][j-1]+1和dp[i-1][j-1]+1的最小值。
AC代码
func minDistance(word1 string, word2 string) int {
m,n:=len(word1),len(word2)
dp:=make([][]int,m+1)
for i:=0;i<len(dp);i++{
dp[i]=make([]int,n+1)
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++{
dp[i][j]=min(dp[i-1][j],dp[i][j-1])
if word1[i-1]==word2[j-1]{
dp[i][j]=min(dp[i][j],dp[i-1][j-1]-1)+1
}else{
dp[i][j]=min(dp[i][j],dp[i-1][j-1])+1
}
}
}
return dp[m][n]
}
func min(a,b int)int{
if a<b{
return a
}
return b
}
感悟
很难,太难了!只能背下来了,依赖于dp[i-1][j]、dp[i][j-1]和dp[i-1][j-1]