Leetcode:Edit Distance 解題報告


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

 

SOLUTION 1:

REF:
http://www.cnblogs.com/etcow/archive/2012/08/30/2662985.html
http://www.cnblogs.com/etcow/archive/2012/08/30/2662985.html
http://blog.csdn.net/fightforyourdream/article/details/13169573
http://www.cnblogs.com/TenosDoIt/p/3465316.html

相當經典的一道遞歸題目,而且難度級別為4.


這是一個典型的2維DP.
定義D[i][j] 為string1 前i個字符串到 string2的前j個字符串的轉化的最小步。
1. 初始化: D[0][0] = 0;  2個為空 不需要轉
2. D[i][0] = D[i - 1][0] + 1. 就是需要多刪除1個字符
3. D[0][j] = D[0][j - 1] + 1. 就是轉完后需要添加1個字符

D[i][j] 的遞推公式:
我們來考慮最后一步的操作:
從上一個狀態到D[i][j],最后一步只有三種可能:
添加,刪除,替換(如果相等就不需要替換)

a、給word1插入一個和word2最后的字母相同的字母,這時word1和word2的最后一個字母就一樣了,此時編輯距離等於1(插入操作) + 插入前的word1到word2去掉最后一個字母后的編輯距離
D[i][j - 1] + 1
例子:  從ab --> cd
我們可以計算從 ab --> c 的距離,也就是 D[i][j - 1],最后再在尾部加上d

b、刪除word1的最后一個字母,此時編輯距離等於1(刪除操作) + word1去掉最后一個字母到word2的編輯距離
D[i - 1][j] + 1
例子:  從ab --> cd
我們計算從 a --> cd 的距離,再刪除b, 也就是 D[i - 1][j] + 1

c 、把word1的最后一個字母替換成word2的最后一個字母,此時編輯距離等於 1(替換操作) + word1和word2去掉最后一個字母的編輯距離。
這里有2種情況,如果最后一個字符是相同的,即是:D[i - 1][j - 1],因為根本不需要替換,否則需要替換,就是
D[i - 1][j - 1] + 1

然后取三種情況下的最小距離

現在來證明一下,當最后一個字符相同時,D[i][j] = D[i - 1][j - 1],這里只要證明D[i - 1][j -1] <=D[i ][j - 1]+1即可。
反證法:
假設:D[i - 1][j -1] > D[i ][j - 1]+1
推論:如果我們要把i-1字符串變換為j - 1,
          我們可以通過先在str1加上一個字符,得到帶前i個字符的str1 , 然后再執行D[i][j -1]
          D[i][j - 1] + 1 也可以推出 i , j 字符串的轉換  也就是說
          推出:D[i - 1][j - 1]不是i - 1--> j - 1轉換的最小值
          推論與題設相矛盾,所以得證。

基於以上證明,當最后一個字符相同時,我們其實可以直接讓D[i][j] = D[i - 1][j - 1].

例子: "ababd" -> "ccabab"

  先初始化matrix如下。意思是,比如"_" -> "cca" = 2 操作是插入'c','c','a',共3步。 "abab" -> "+ "_" 刪除'a','b','a','b',共4 步。

  _ a b a b d
_ 0 1 2 3 4 5
c 1          
c 2          
a 3          
b 4          
a 5          
b 6          

  然后按照注釋里的方法填滿表格,返回最后一個數字(最佳解)

 

  _ a b a b d
_ 0 1 2 3 4 5
c 1 1 2 3 4 5
c 2 2 2 3 4 5
a 3 2 3 2 3 4
b 4 3 2 3 2 3
a 5 4 3 2 3 3
b 6 5 4 3 2 3
 1 public class Solution {
 2     public int minDistance(String word1, String word2) {
 3         if (word1 == null || word2 == null) {
 4             return 0;
 5         }
 6         
 7         int len1 = word1.length();
 8         int len2 = word2.length();
 9         
10         int[][] D = new int[len1 + 1][len2 + 1];
11         
12         for (int i = 0; i <= len1; i++) {
13             for (int j = 0; j <= len2; j++) {
14                 if (i == 0) {
15                     D[i][j] = j;
16                 } else if (j == 0) {
17                     D[i][j] = i;
18                 } else {
19                     if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
20                         D[i][j] = D[i - 1][j - 1];
21                     } else {
22                         D[i][j] = Math.min(D[i - 1][j - 1], D[i][j - 1]);
23                         D[i][j] = Math.min(D[i][j], D[i - 1][j]);
24                         D[i][j]++;
25                     }
26                 }
27             }
28         }
29         
30         return D[len1][len2];
31     }
32 }
View Code

GitHub代碼鏈接


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM