zoukankan      html  css  js  c++  java
  • Leetcode | Edit Distance

    Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)

    You have the following 3 operations permitted on a word:

    a) Insert a character
    b) Delete a character
    c) Replace a character

    这道题本来倒是一看就觉得应该是DP,因为有两个串,所以很自然地想用一个二维数组来保存中间结构,即用min[i][j]来表示word1[0...i]和word2[0...j]的最小edit distance.

    进行递推求解的时候,初始是需要知道,min[i][0]和min[0][i]的值的,这个好算。不过注意当出现word1[i]=word2[0]或者word2[i] == word1[0]时有少许不同。比如word1="bbab",word2="a",那么min[0][0]=1,min[1][0]=2,min[2][0]=2,min[3][0]=3;

    dp的公式如下:

    min[i][j] = min[i-1][j-1], if word1[i] == word2[j];

         = min{min[i-1][j-1], min[i - 1][j], min[i][j - 1]}, else; //对应于三种情况(插入、删除、替换)

    代码如下:

     1 class Solution {
     2 public:
     3     int minDistance(string word1, string word2) {
     4         int n1 = word1.length();
     5         int n2 = word2.length();
     6         if (n1 == 0) return n2;
     7         if (n2 == 0) return n1;
     8         vector<vector<int> > min(n1, vector<int>(n2, 0));
     9         
    10         bool flag = false;
    11         for (int i = 0; i < n1; ++i) {
    12             if (word1[i] == word2[0]) { 
    13                 min[i][0] = i;
    14                 flag = true;
    15             } else {
    16                 if (flag) min[i][0] = i;
    17                 else min[i][0] = i + 1;
    18             }
    19         }
    20         
    21         flag = false;
    22         for (int i = 0; i < n2; ++i) {
    23             if (word1[0] == word2[i]) { 
    24                 min[0][i] = i;
    25                 flag = true;
    26             } else {
    27                 if (flag) min[0][i] = i;
    28                 else min[0][i] = i + 1;
    29             }
    30         }
    31         
    32         for (int i = 1; i < n1; ++i) {
    33             for (int j = 1; j < n2; ++j) {
    34                 if (word1[i] == word2[j]) {
    35                     min[i][j] = min[i - 1][j - 1];
    36                 } else {
    37                     int m = min[i - 1][j] + 1;
    38                     if (min[i][j - 1] + 1 < m) {
    39                         m = min[i][j - 1] + 1;
    40                     }
    41                     if (min[i - 1][j - 1] + 1 < m) {
    42                         m = min[i - 1][j - 1] + 1;
    43                     }
    44                     min[i][j] = m;
    45                 }
    46             }
    47         }
    48         
    49         return min[n1 - 1][n2 - 1];
    50     }
    51     
    52 };

     后来看到网上有人把min[i][j]中i和j理解为长度,这样多用了一些空间,不过效率高了一些,不需要在初始化的时候做分别处理。

  • 相关阅读:
    08简单推导:手机尾号评分
    07简单推导:生日蜡烛
    06普通推导
    05简单推导:猴子吃桃
    简单推导
    03map用法
    List题目
    02List的使用
    01基础知识
    HDU
  • 原文地址:https://www.cnblogs.com/linyx/p/3708199.html
Copyright © 2011-2022 走看看