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 ...
随机推荐
- Use Sandcastle Help File Builder to generate help document
http://shfb.codeplex.com/ Note: If the the help file contains the text "[Missing <param> ...
- 在Java中执行js代码
在某些特定场景下,我们需要用Java来执行Js代码(如模拟登录时,密码被JS加密了的情况),操作如下: ScriptEngineManager mgr = new ScriptEngineManage ...
- C# sogou地图API应用总结
地图的初始化1.添加引用地图的API文件: <script src="http://api.go2map.com/maps/js/api_v2.5.1.js" type=&q ...
- Error NO.2013 Lost connection to Mysql server during query
系统:[root@hank-yoon ~]# cat /etc/redhat-release CentOS release 6.3 (Final) DB版本:mysql> select @@ve ...
- CentOS安装 pure-ftpd
yum -y install pam-devel cd /usr/local .tar.gz cd pure-ftpd- ./configure --prefix=/usr/local/pure-ft ...
- SVN学习
一.SVN在线安装(Eclipse) 步骤1: 步骤2 其中http://subclipse.tigris.org/update_1.10.x是最新版本的SVN插件的下载站点[subclipse是Ec ...
- 模仿开发H5游戏,看你有多色
开发记录 前言 之前跟着慕课网学习开发H5小游戏开心鱼,勾起我的兴趣. 在写代码的过程中,不怎么会遇到问题.虽然代码是亲手敲出来的,但是由于并没有对游戏的整体思路,所以并不知道开发与优化的过程. 为了 ...
- C#的配置文件App.config使用总结 - 转
http://blog.csdn.net/celte/article/details/9749389 首先,先说明,我使用的app.config 配置文件的格式如下: <?xml version ...
- 1226: [SDOI2009]学校食堂Dining - BZOJ
Description 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以 ...
- java.util.ConcurrentModificationException 解决办法(转)
今天在项目的中有一个需求,需要在一个Set类型的集合中删除满足条件的对象,这时想当然地想到直接调用Set的remove(Object o)方法将指定的对象删除即可,测试代码: public cla ...