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.)java
You have the following 3 operations permitted on a word:算法
a) Insert a character
b) Delete a character
c) Replace a character數據結構
【思路分析】ui
編輯距離是一道很經典的動態規劃的算法題目。spa
編輯距離,又稱Levenshtein距離(萊文斯坦距離也叫作Edit Distance),是指兩個字串之間,由一個轉成另外一個所需的最少編輯操做次數,若是它們的距離越大,說明它們越是不一樣。許可的編輯操做包括將一個字符替換成另外一個字符,插入一個字符,刪除一個字符。.net
這個概念是由俄羅斯科學家Vladimir Levenshtein在1965年提出來的,因此也叫 Levenshtein 距離。它能夠用來作DNA分析,拼字檢測,抄襲識別等等。老是比較類似的,或多或少咱們能夠考慮編輯距離。code
在概念中,咱們能夠看出一些重點那就是,編輯操做只有三種。插入,刪除,替換這三種操做,咱們有兩個字符串,將其中一個字符串通過上面的這三種操做以後,獲得兩個徹底相同的字符串付出的代價是什麼就是咱們要討論和計算的。blog
例如:
咱們有兩個字符串: kitten 和 sitting:
如今咱們要將kitten轉換成sitting
咱們能夠作以下的一些操做;圖片
k i t t e n –> s i t t e n 將K替換成S字符串
sitten –> sittin 將 e 替換成i
sittin –> sitting 添加g
在這裏咱們設置每通過一次編輯,也就是變化(插入,刪除,替換)咱們花費的代價都是1。
例如:
若是str1=」ivan」,str2=」ivan」,那麼通過計算後等於 0。沒有通過轉換。類似度=1-0/Math.Max(str1.length,str2.length)=1
若是str1=」ivan1」,str2=」ivan2」,那麼通過計算後等於1。str1的」1」轉換」2」,轉換了一個字符,因此距離是1,類似度=1-1/Math.Max(str1.length,str2.length)=0.8
1.str1或str2的長度爲0返回另外一個字符串的長度。 if(str1.length==0) return str2.length; if(str2.length==0) return str1.length;
2.初始化(n+1)*(m+1)的矩陣d,並讓第一行和列的值從0開始增加。掃描兩字符串(n*m級的),若是:str1[i] == str2[j],用temp記錄它,爲0。不然temp記爲1。而後在矩陣d[i,j]賦於d[i-1,j]+1 、d[i,j-1]+一、d[i-1,j-1]+temp三者的最小值。
3.掃描完後,返回矩陣的最後一個值d[n][m]便是它們的距離。
計算類似度公式:1-它們的距離/兩個字符串長度的最大值。
其實這個算法並不難實現
咱們用字符串「ivan1」和「ivan2」舉例來看看矩陣中值的情況:
一、第一行和第一列的值從0開始增加
圖一
首先咱們先建立一個矩陣,或者說是咱們的二維數列,假設有兩個字符串,咱們的字符串的長度分別是m和n,那麼,咱們矩陣的維度就應該是(m+1)*(n+1).
注意,咱們先給數列的第一行第一列賦值,從0開始遞增賦值。咱們就獲得了圖一的這個樣子
以後咱們計算第一列,第二列,依次類推,算完整個矩陣。
咱們的計算規則就是:
d[i,j]=min(d[i-1,j]+1 、d[i,j-1]+一、d[i-1,j-1]+temp) 這三個當中的最小值。
其中:str1[i] == str2[j],用temp記錄它,爲0。不然temp記爲1
咱們用d[i-1,j]+1表示增長操做
d[i,j-1]+1 表示咱們的刪除操做
d[i-1,j-1]+temp表示咱們的替換操做
二、舉證元素的產生 Matrix[i - 1, j] + 1 ; Matrix[i, j - 1] + 1 ; Matrix[i - 1, j - 1] + t 三者當中的最小值
3.依次類推直到矩陣所有生成
這個就獲得了咱們的整個完整的矩陣。
【java代碼】
1 class Solution { 2 public int minDistance(String word1, String word2) { 3 int len1 = word1.length(); 4 int len2 = word2.length(); 5 6 if(len1 == 0) return len2; 7 if(len2 == 0) return len1; 8 9 int[] dp = new int[len1+1]; 10 11 for(int j = 0; j <= len1; j++) { 12 dp[j] = j; 13 } 14 15 for(int i = 1; i <= len2; i++) { 16 int pre = dp[0]; 17 dp[0] = i; 18 19 for(int j = 1; j <= len1; j++) { 20 int temp = dp[j]; 21 int k = 0; 22 if(word1.charAt(j-1) != word2.charAt(i-1)) k = 1; 23 dp[j] = Math.min(Math.min(dp[j-1], dp[j]) + 1, pre+k); 24 pre = temp; 25 } 26 } 27 28 return dp[len1]; 29 } 30 }