📌  相关文章
📜  使两个字符串相等所需的最小给定操作数(1)

📅  最后修改于: 2023-12-03 15:22:07.929000             🧑  作者: Mango

使两个字符串相等所需的最小给定操作数

介绍

给定两个字符串 s 和 t,你需要通过以下操作将字符串 s 转换成字符串 t:

  1. 将 s 中的某个字符替换成另一个字符。
  2. 删除 s 中的一个字符。
  3. 在 s 中插入一个字符。

你可以执行以上三种操作中的任意一种或多种,求出使得两个字符串相等所需的最小操作数。

思路

使用动态规划(DP)求解。

设 dp[i][j] 表示将字符串 s[0...i-1] 转换为字符串 t[0...j-1] 所需的最小操作数。

对于两个指针 i 和 j,存在以下两种情况:

  1. 当 s[i-1] == t[j-1] 时,不需要进行操作,dp[i][j] = dp[i-1][j-1];

  2. 当 s[i-1] != t[j-1] 时,需要进行操作,此时有三种操作方式:

    1. 替换 s[i-1] 为 t[j-1],dp[i][j] = dp[i-1][j-1] + 1;
    2. 删除 s[i-1],dp[i][j] = dp[i-1][j] + 1;
    3. 在 s[i-1] 后插入 t[j-1],dp[i][j] = dp[i][j-1] + 1。

综上,dp[i][j] 可以表示为:

  1. 如果 s[i-1] == t[j-1],dp[i][j] = dp[i-1][j-1];
  2. 如果 s[i-1] != t[j-1],dp[i][j] = min(dp[i-1][j-1]+1, dp[i-1][j]+1, dp[i][j-1]+1)。

最终的结果即为 dp[len(s)][len(t)]。

代码实现如下:

def min_operation(s: str, t: str) -> int:
    m, n = len(s), len(t)
    dp = [[0] * (n+1) for _ in range(m+1)]
    
    # 当 s 为空字符串时,需要进行 n 次插入操作才能变成 t
    for j in range(1, n+1):
        dp[0][j] = j
    
    # 当 t 为空字符串时,需要进行 m 次删除操作才能变成 s
    for i in range(1, m+1):
        dp[i][0] = i
        
    for i in range(1, m+1):
        for j in range(1, n+1):
            if s[i-1] == t[j-1]:
                dp[i][j] = dp[i-1][j-1]
            else:
                dp[i][j] = min(dp[i-1][j-1]+1, dp[i-1][j]+1, dp[i][j-1]+1)
    
    return dp[m][n]
示例
s = "horse"
t = "ros"
print(min_operation(s, t))  # 输出 3,需要进行 1 次替换操作和 2 次删除操作

s = "intention"
t = "execution"
print(min_operation(s, t))  # 输出 5,需要进行 3 次插入操作和 2 次删除操作
总结

本题是一道经典的字符串 DP 题目,需要熟练掌握动态规划的思路,理解 DP 方程的含义。在实现时,可以使用二维数组进行状态转移,代码模板也可以借鉴本文的实现。