题目:

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. 3. opencv进行SIFT特征提取

    opencv中sift特征提取的步骤 使用SiftFeatureDetector的detect方法检测特征存入一个向量里,并使用drawKeypoints在图中标识出来 SiftDescriptorE ...

  2. 说说iOS中的手势及触摸

    一.响应链 在IOS开发中会遇到各种操作事件,通过程序可以对这些事件做出响应. 首先,当发生事件响应时,必须知道由谁来响应事件.在IOS中,由响应者链来对事件进行响应,所有事件响应的类都是UIResp ...

  3. cocos3.2中如何创建一个场景

    1.可以将一些比较通用的东西放到Common.h中,这是一个.h文件,必须手动添加,且保证在classes目录里 #ifndef __COMMON_H__ #define __COMMON_H__ # ...

  4. C# - 设置DLL的属性Embed Interop Type 设为False

    错误: Error msg: A reference was created to embedded interop assembly. because of an indirect referenc ...

  5. DevExpress控件使用系列--ASPxGridView+Popup+Tab

      1.控件功能     列表控件展示数据.弹框控件执行编辑操作.Tab控件实现多标签编辑操官方说明 2.官方示例       2.1 ASPxGridView                http ...

  6. Leetcode#81 Search in Rotated Sorted Array II

    原题地址 如果不存在重复元素,仅通过判断数组的首尾元素即可判断数组是否连续,但是有重复元素的话就不行了,最坏情况下所有元素都一样,此时只能通过线性扫描确定是否连续. 设对于规模为n的问题的工作量为T( ...

  7. Filter及FilterChain的使用详解(转)

    一.Filter的介绍及使用 什么是过滤器? 与Servlet相似,过滤器是一些web应用程序组件,可以绑定到一个web应用程序中.但是与其他web应用程序组件不同的是,过滤器是"链&quo ...

  8. NGUI Tutorial 3

    一. Create a Button 一.(Menu)NGUI -> Create -> Sprite 二.attach box colider to the Sprite , then ...

  9. C++中的const关键字

    http://blog.csdn.net/eric_jo/article/details/4138548 C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方 ...

  10. How do you design object oriented projects?

    what are things you do during the high level design phase (before you begin programming) to determin ...