72. 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
链接: 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];
}
}
二刷
思路仍然不是特别清晰。我们尝试分为以下几个步骤:
- 这道题目应该使用dp。
- 要解决的是如何定义dp, 如何设置初始化状态,以及转移方程是什么。
- 首先我们考虑边界条件,当有一个string为空的时候我们返回0。
- 接下来创建一个dp矩阵dist,假如word1的长度为word1Len,word2的长度为word2Len,那么这个矩阵的长度就为[word1Len + 1, word2Len + 1]。
- 我们初始化第一行和第一列,dist[i][0] = i, dist[0][j] = j, 都是负责处理其中一个word为空这种情况。
- 接下来,我们定义dist[i][j]为 word1(0, i) 到word2(0,j) 这两个单词的min Edit distance。那么我们有以下的公式:
- 假如word1.charAt(i) == word2.charAt(j),那么dist[i][j] = 0
- 否则dist[i][j] = 1 + min (dist[i - 1][j - 1], min(dist[i - 1][j], dist[i][j - 1]))。
- 这里假如使用dist[i - 1][j - 1],意思是replace
- 假如使用dist[i - 1][j],那么是word1比word2少1个字符。 对word1来说是add
- 假如使用dist[i][j - 1],那么是word2比word1多一个字符。对word1来说是delete
- 最后返回结果dist[word1Len][word2Len]
- 这里其实也可以简化为滚动数组,达到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的更多相关文章
- 【Leetcode】72 Edit Distance
72. Edit Distance Given two words word1 and word2, find the minimum number of steps required to conv ...
- 刷题72. Edit Distance
一.题目说明 题目72. Edit Distance,计算将word1转换为word2最少需要的操作.操作包含:插入一个字符,删除一个字符,替换一个字符.本题难度为Hard! 二.我的解答 这个题目一 ...
- [LeetCode] 72. Edit Distance 编辑距离
Given two words word1 and word2, find the minimum number of operations required to convert word1 to ...
- leetCode 72.Edit Distance (编辑距离) 解题思路和方法
Edit Distance Given two words word1 and word2, find the minimum number of steps required to convert ...
- [LeetCode] 72. Edit Distance(最短编辑距离)
传送门 Description Given two words word1 and word2, find the minimum number of steps required to conver ...
- 72. Edit Distance *HARD*
Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2 ...
- LeetCode - 72. Edit Distance
最小编辑距离,动态规划经典题. Given two words word1 and word2, find the minimum number of steps required to conver ...
- 72. Edit Distance(困难,确实挺难的,但很经典,双序列DP问题)
Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2 ...
- 【一天一道LeetCode】#72. Edit Distance
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given t ...
随机推荐
- Linq--扩展方法
如果现在有一个这样的需求,求筛选出来的大于20MB的进程的和,常用的方法是写一个静态方法传进去一个ProcessData列表 比如: public static Int64 TotalMemory( ...
- selenium+python find_element_by_css_selector方法使用
1.通过类class获取 比如如下代码 <h1 class="important"> This heading is very important. </h1&g ...
- vs2012用wpf制作透明窗口中报错的解决方案
在开发wpf项目时,需要调用外部com组件,同时需要制作透明窗口,于是问题出现了,当我们在设置 AllowsTransparency="True"后,com组件显示不出来了,只有透 ...
- 【quartz】 入门
把技术债务给还了,首先来一个最简单的demo: 2.x版比1.x有很多改进,1.x基于fw1.2: 2.x基于fw3.5以上:语法上有很大的不同,摒弃了很多1.x的很多东西: 直接以2.x来demo ...
- IE8的Textarea滚动条乱跳的解决方案
最近在弄的一个项目,其中一个页面需要输入很长的文字,因为文字是纯文本的,所以用了Textarea,在webkit下没有任何问题,结果在IE8下测试时,发现当文本超超出Textarea的大小时,在输入文 ...
- VBS基础篇 - 循环
经常地,当编写代码时,我们希望将一段代码执行若干次,我们可以在代码中使用循环语句来完成这项工作. 循环可分为三类:一类在条件变为 False 之前重复执行语句,一类在条件变为 True 之前重复执行语 ...
- C# book
<编写高质量代码:改善C#程序的157个建议>源码下载 http://www.cnblogs.com/luminji/archive/2011/09/20/2182265.html < ...
- 【最小生成树】BZOJ 1196: [HNOI2006]公路修建问题
1196: [HNOI2006]公路修建问题 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1435 Solved: 810[Submit][Sta ...
- 【POJ】【2125】Destroying the Graph
网络流/二分图最小点权覆盖 果然还是应该先看下胡伯涛的论文…… orz proverbs 题意: N个点M条边的有向图,给出如下两种操作.删除点i的所有出边,代价是Ai.删除点j的所有入边,代价是Bj ...
- docker设置代理
在天朝使用docker需要FQ. 下面给出docker的代理方式: HTTP_PROXY=http://10.167.251.83:8080 docker -d