题目:

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

链接:  http://leetcode.com/problems/edit-distance/

题解:

Dynamic Programming动态规划的经典问题,一定要好好继续研究一下。 详解请看下面的reference。 还可以使用滚动数组继续优化空间为O(n)或者O(m)。最近在忙于房子装修,都没有时间刷题和准备面试,下一遍要补上。

下周一onsite BB,裸面,希望有好运气吧!

Time Complexity - O(mn), Space Complexity - O(mn)。

public class Solution {
public int minDistance(String word1, String word2) {
if(word1 == null || word2 == null)
return 0;
int word1Len = word1.length(), word2Len = word2.length();
int[][] dp = new int[word1Len + 1][word2Len + 1]; for(int i = 0; i < word1Len + 1; i++) //word1 as row
dp[i][0] = i; for(int j = 1; j < word2Len + 1; j++) //word2 as column
dp[0][j] = j; for(int i = 1; i < word1Len + 1; i++) {
for(int j = 1; j < word2Len + 1; j++) {
if(word1.charAt(i - 1) == word2.charAt(j - 1))
dp[i][j] = dp[i - 1][j - 1];
else
dp[i][j] = 1 + Math.min(dp[i - 1][j - 1], Math.min(dp[i][j - 1], dp[i - 1][j]));
}
} return dp[word1Len][word2Len];
}
}

Update:

主要使用DP,假设以word1为列,word2为行,初始化的时候设定distance[0][i]以及distance[j][0] - 当对方字符串为空时需要多少步骤。则转移方程为,当前字符相同时,distance[i][j] = distance[i - 1][j - 1], 否则这时insert, replace,delete权重都为1, 方程为1 + 三种改变的最小值, 既Math.min(distance[i - 1][j - 1], Math.min(distance[i - 1][j], distance[i][j - 1]))。 其中distance[i - 1][j - 1]为replace, distance[i - 1][j]是word1删除一个字符, distance[i][j - 1]是word2删除一个字符。

public class Solution {
public int minDistance(String word1, String word2) {
if(word1 == null || word2 == null)
return 0;
int word1Len = word1.length(), word2Len = word2.length();
int[][] distance = new int[word1Len + 1][word2Len + 1]; for(int i = 1; i < word1Len + 1; i++)
distance[i][0] = i; for(int j = 1; j < word2Len + 1; j++)
distance[0][j] = j; for(int i = 1; i < word1Len + 1; i++) {
for(int j = 1; j < word2Len + 1; j++)
if(word1.charAt(i - 1) == word2.charAt(j - 1))
distance[i][j] = distance[i - 1][j - 1];
else
distance[i][j] = 1 + Math.min(distance[i - 1][j - 1], Math.min(distance[i - 1][j], distance[i][j - 1]));
} return distance[word1Len][word2Len];
}
}

二刷

思路仍然不是特别清晰。我们尝试分为以下几个步骤:

  1. 这道题目应该使用dp。
  2. 要解决的是如何定义dp,  如何设置初始化状态,以及转移方程是什么。
  3. 首先我们考虑边界条件,当有一个string为空的时候我们返回0。
  4. 接下来创建一个dp矩阵dist,假如word1的长度为word1Len,word2的长度为word2Len,那么这个矩阵的长度就为[word1Len + 1, word2Len + 1]。
  5. 我们初始化第一行和第一列,dist[i][0] = i, dist[0][j] = j,  都是负责处理其中一个word为空这种情况。
  6. 接下来,我们定义dist[i][j]为 word1(0, i) 到word2(0,j) 这两个单词的min Edit distance。那么我们有以下的公式:
    1. 假如word1.charAt(i) == word2.charAt(j),那么dist[i][j] = 0
    2. 否则dist[i][j] = 1 + min (dist[i - 1][j - 1], min(dist[i - 1][j], dist[i][j - 1]))。
      1. 这里假如使用dist[i - 1][j - 1],意思是replace
      2. 假如使用dist[i - 1][j],那么是word1比word2少1个字符。 对word1来说是add
      3. 假如使用dist[i][j - 1],那么是word2比word1多一个字符。对word1来说是delete
  7. 最后返回结果dist[word1Len][word2Len]
  8. 这里其实也可以简化为滚动数组,达到Space Complexity - O(n)的结果,留给三刷了。

Java:

Time Complexity - O(mn), Space Complexity - O(mn)。

public class Solution {
public int minDistance(String word1, String word2) {
if (word1 == null || word2 == null) {
return 0;
}
int word1Len = word1.length(), word2Len = word2.length();
int[][] dist = new int[word1Len + 1][word2Len + 1];
for (int i = 1; i <= word1Len; i++) {
dist[i][0] = i;
}
for (int j = 1; j <= word2Len; j++) {
dist[0][j] = j;
} for (int i = 1; i <= word1Len; i++) {
for (int j = 1; j <= word2Len; j++) {
if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
dist[i][j] = dist[i - 1][j - 1];
} else {
dist[i][j] = Math.min(dist[i - 1][j - 1], Math.min(dist[i - 1][j], dist[i][j - 1])) + 1;
}
}
} return dist[word1Len][word2Len];
}
}

三刷:

还是dp。当两字符相等时,取左上的值。 否则表示有一个edit distance,我们取左上,上和左三个值里最小的一个,+ 1,然后继续计算。

Java:

public class Solution {
public int minDistance(String word1, String word2) {
if (word1 == null || word2 == null) return Integer.MAX_VALUE;
int m = word1.length(), n = word2.length();
int[][] dp = new int[m + 1][n + 1];
for (int i = 1; i <= m; i++) dp[i][0] = i;
for (int j = 1; j <= n; j++) dp[0][j] = j; for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (word1.charAt(i - 1) == word2.charAt(j - 1)) dp[i][j] = dp[i - 1][j - 1];
else dp[i][j] = 1 + Math.min(dp[i - 1][j - 1], Math.min(dp[i - 1][j], dp[i][j - 1]));
}
}
return dp[m][n];
}
}

一维DP:

跟Maximal Square一样,也是使用一个topLeft来代表左上方的元素。

public class Solution {
public int minDistance(String word1, String word2) {
if (word1 == null || word2 == null) return Integer.MAX_VALUE;
int m = word1.length(), n = word2.length();
if (m == 0) return n;
else if (n == 0) return m; int[] dp = new int[n + 1];
for (int j = 1; j <= n; j++) dp[j] = j;
int topLeft = 0; for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
int tmp = dp[j];
if (word1.charAt(i - 1) == word2.charAt(j - 1)) dp[j] = topLeft;
else dp[j] = 1 + Math.min(topLeft, Math.min(dp[j], dp[j - 1]));
topLeft = tmp;
}
dp[0] = i;
topLeft = i;
}
return dp[n];
}
}

Reference:

https://leetcode.com/discuss/10426/my-o-mn-time-and-o-n-space-solution-using-dp-with-explanation

http://www.cnblogs.com/springfor/p/3896167.html

https://leetcode.com/discuss/17997/my-accepted-java-solution

https://leetcode.com/discuss/20945/standard-dp-solution

https://leetcode.com/discuss/5138/good-pdf-on-edit-distance-problem-may-be-helpful

https://leetcode.com/discuss/43398/20ms-detailed-explained-c-solutions-o-n-space

http://web.stanford.edu/class/cs124/lec/med.pdf

https://en.wikipedia.org/wiki/Edit_distance

https://leetcode.com/discuss/64063/ac-python-212-ms-dp-solution-o-mn-time-o-n-space

https://leetcode.com/discuss/43398/20ms-detailed-explained-c-solutions-o-n-space

72. Edit Distance的更多相关文章

  1. 【Leetcode】72 Edit Distance

    72. Edit Distance Given two words word1 and word2, find the minimum number of steps required to conv ...

  2. 刷题72. Edit Distance

    一.题目说明 题目72. Edit Distance,计算将word1转换为word2最少需要的操作.操作包含:插入一个字符,删除一个字符,替换一个字符.本题难度为Hard! 二.我的解答 这个题目一 ...

  3. [LeetCode] 72. Edit Distance 编辑距离

    Given two words word1 and word2, find the minimum number of operations required to convert word1 to  ...

  4. leetCode 72.Edit Distance (编辑距离) 解题思路和方法

    Edit Distance Given two words word1 and word2, find the minimum number of steps required to convert  ...

  5. [LeetCode] 72. Edit Distance(最短编辑距离)

    传送门 Description Given two words word1 and word2, find the minimum number of steps required to conver ...

  6. 72. Edit Distance *HARD*

    Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2 ...

  7. LeetCode - 72. Edit Distance

    最小编辑距离,动态规划经典题. Given two words word1 and word2, find the minimum number of steps required to conver ...

  8. 72. Edit Distance(困难,确实挺难的,但很经典,双序列DP问题)

    Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2 ...

  9. 【一天一道LeetCode】#72. Edit Distance

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given t ...

随机推荐

  1. Linq--扩展方法

    如果现在有一个这样的需求,求筛选出来的大于20MB的进程的和,常用的方法是写一个静态方法传进去一个ProcessData列表 比如: public static Int64 TotalMemory( ...

  2. selenium+python find_element_by_css_selector方法使用

    1.通过类class获取 比如如下代码 <h1 class="important"> This heading is very important. </h1&g ...

  3. vs2012用wpf制作透明窗口中报错的解决方案

    在开发wpf项目时,需要调用外部com组件,同时需要制作透明窗口,于是问题出现了,当我们在设置 AllowsTransparency="True"后,com组件显示不出来了,只有透 ...

  4. 【quartz】 入门

    把技术债务给还了,首先来一个最简单的demo: 2.x版比1.x有很多改进,1.x基于fw1.2: 2.x基于fw3.5以上:语法上有很大的不同,摒弃了很多1.x的很多东西: 直接以2.x来demo ...

  5. IE8的Textarea滚动条乱跳的解决方案

    最近在弄的一个项目,其中一个页面需要输入很长的文字,因为文字是纯文本的,所以用了Textarea,在webkit下没有任何问题,结果在IE8下测试时,发现当文本超超出Textarea的大小时,在输入文 ...

  6. VBS基础篇 - 循环

    经常地,当编写代码时,我们希望将一段代码执行若干次,我们可以在代码中使用循环语句来完成这项工作. 循环可分为三类:一类在条件变为 False 之前重复执行语句,一类在条件变为 True 之前重复执行语 ...

  7. C# book

    <编写高质量代码:改善C#程序的157个建议>源码下载 http://www.cnblogs.com/luminji/archive/2011/09/20/2182265.html < ...

  8. 【最小生成树】BZOJ 1196: [HNOI2006]公路修建问题

    1196: [HNOI2006]公路修建问题 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1435  Solved: 810[Submit][Sta ...

  9. 【POJ】【2125】Destroying the Graph

    网络流/二分图最小点权覆盖 果然还是应该先看下胡伯涛的论文…… orz proverbs 题意: N个点M条边的有向图,给出如下两种操作.删除点i的所有出边,代价是Ai.删除点j的所有入边,代价是Bj ...

  10. docker设置代理

    在天朝使用docker需要FQ. 下面给出docker的代理方式: HTTP_PROXY=http://10.167.251.83:8080 docker -d