hard题,看上去就挺可怕的,仔细一想想觉得很清晰,希望自己早日能达到这种逻辑。
题目🔗
算法思路
题解思路链接🔗
- 状态:
- dp[i, j] i代表【0,i】的word1 j代表【0,j】的word2 dp[ i ][ j ]表示word1[ 0 : i ] 和word2[ 0 : j ]
- 选择:
- 插入一个字符串 dp[ i ][ j - 1 ] + 1
- 删除一个字符串 dp[ i - 1 ][ j ] + 1
- 替换一个字符串 dp[ i - 1 ][ j - 1 ] + 1
- 跳过啥都不做 dp[ i - 1 ][ j - 1 ]
- 状态转移方程:
- dp[i][j] =
- if word1[i]==word2[j] 跳过 --> dp[i-1]dp[j-1]
- else 进行相应操作 --> min(插入, 删除, 替换)--> min(dp[i][j-1], dp[i-1][j], dp[i-1][j-1])
- base case:
- 由于i , j 应该初始化成-1才对,但是数组下表从0开始,所以以0为base case dp向右偏移了一位, 所以dp的大小也要大一位
class Solution:
def minDistance(self, word1: str, word2: str) -> int:
# 状态dp[i, j], i代表【0,i】的word1 j代表【0,j】的word2 dp[i][j]表示word1[0:i] 和word2[0:j]
# 选择: 1. 插入一个字符串 2. 删除一个字符串 3. 替换一个字符串 4. 跳过啥都不做
# 状态转移方程 dp[i][j] = if word1[i]==word2[j] 跳过 --> dp[i-1]dp[j-1]
# else 进行相应操作 --> min(插入, 删除, 替换)--> min(dp[i][j-1], dp[i-1][j], dp[i-1]dp[j-1])
# base case 由于i,j应该初始化成-1才对 但是数组下表从0开始 所以以0为base case dp向右偏移了以为 所以dp的大小也要大一位
n, m = len(word1), len(word2)
dp = [[0]*(m+1) for i in range(n+1)]
# base case
for i in range(1,n+1):
dp[i][0] = i # 注意这里别写错啦
for j in range(1,m+1):
dp[0][j] = j
# begin
for i in range(1, n+1):
for j in range(1, m+1):
if word1[i-1] == word2[j-1]: # 注意这里偏移了一位!
dp[i][j] = dp[i-1][j-1] # 啥也不做
else:
dp[i][j] = min([dp[i][j-1], dp[i-1][j], dp[i-1][j-1]])+1 # 注意这里操作数+1
return dp[n][m]