72_Edit_distance_编辑距离

题目描述

Given two strings word1 and word2, return the minimum number of operations required to convert word1 to word2.

You have the following three operations permitted on a word:

  • Insert a character
  • Delete a character
  • Replace a character

给定两个字符串word1word2, 求 编辑距离

基本思想

这是一个二维动态规划问题。假设word1的长度为n,word2的长度为m。

构建数组 dp, 则 \(dp[i][j]\) 表示 word1[0 ~ i] 转换成 word2[0~j] 相应的编辑距离。\(dp[i][j]\) 的更新公式如下:

  • 如果 \(word1[i] == word2[j]\), 则 $dp[i][j] $ = $dp[i-1][-1j] $
  • 如果 \(word1[i] != word2[j]\), 则 有三种情况可以将word1[0 ~ i] 转换为 word2[0~j]
    • 删除元素: word1[0~ i-1] 转换为 word2[0 ~ j] 的编辑距离是x1, word1[0~i] 删除 word1[i] 这个元素,可以得到 word2[0~j]
    • 增加元素: word1[0~ i] 转换为 word2[0 ~ j-1] 的编辑距离是x2, 则 word1[0~ i] 转换为 word2[0 ~ j-1] 之后,再增加一个元素word2[j] 既可以
    • 替换元素:word1[0~ i-1] 转换为 word2[0 ~ j-1]的编辑距离是x3, 当转化完毕之后,将word1[i] 替换为word2[j] 即可
    • 综上,当 \(word1[i] != word2[j]\) , $dp[i][j] $ = min(x1+1, x2+1, x3+1)

时间复杂度\(o(n^2)\)

代码

C++

    int minDistance(string word1, string word2) {
        int n = word1.size();
        int m = word2.size();
        if (n<=0) return m;
        if (m<=0) return n;
        vector<vector<int>> dp(n+1,vector<int>(m+1,0)); // dp[i,j] 表示 word[0~i] 转换到 word[0~j] 的编辑距离
        // 1- 初始化
        for(int i=0;i<=m;++i) {
            dp[0][i] = i;
        } 
        for(int i=0;i<=n;++i) {
            dp[i][0] = i;
        }
        for(int i=1;i<=n;++i) {
            for(int j=1; j<=m;++j) {
                int t = m+n;
                if (word1[i-1] == word2[j-1]) {
                    t = dp[i-1][j-1]; 
                } else {
                    t = min(min(dp[i-1][j]+1, dp[i][j-1]+1), dp[i-1][j-1]+1);
                }
                dp[i][j] = t;
            }
        }
        return dp[n][m];
    }

python

    def minDistance(self, word1: str, word2: str) -> int:
      m = len(word1)
      n = len(word2)
      if m<=0: return n
      if n<=0: return m   # 很重要
      dp = [ [ 0 for j in range(n+1)] for i in range(m+1)]
      # 1. 初始化
      for i in range(m+1):
        dp[i][0] = i
      for i in range(n+1):
        dp[0][i] = i
      for i in range(1, m+1):
          for j in range(1, n+1):
            if word1[i-1] == word2[j-1]:
              dp[i][j] = dp[i-1][j-1]
            else :
              t = min(dp[i-1][j] + 1,dp[i][j-1] + 1)
              dp[i][j] = min(t, dp[i-1][j-1] + 1)
      return dp[m][n]
posted @ 2024-05-13 22:23  金字塔下的蜗牛  阅读(2)  评论(0编辑  收藏  举报