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 }