Given two strings word1 and word2, return the minimum number of operations required to convert word1 to word2.
You have the following three operations permitted on a word:
- Insert a character
- Delete a character
- Replace a character
Example 1:
Input: word1 = "horse", word2 = "ros" Output: 3 Explanation: horse -> rorse (replace 'h' with 'r') rorse -> rose (remove 'r') rose -> ros (remove 'e')
Example 2:
Input: word1 = "intention", word2 = "execution" Output: 5 Explanation: intention -> inention (remove 't') inention -> enention (replace 'i' with 'e') enention -> exention (replace 'n' with 'x') exention -> exection (replace 'n' with 'c') exection -> execution (insert 'u')
Constraints:
0 <= word1.length, word2.length <= 500word1andword2consist of lowercase English letters.
---------------------3rd pass----------------rolling table----------
class Solution {
public:
int minDistance(string word1, string word2) {
int n1 = word1.length();
vector<int> dp;
for(int i =0; i<= n1; i++)
dp.push_back(i);
for(auto ch : word2){
vector<int> dp_old = dp;
for(int i = 0; i<=n1; i++){
if(i==0){
dp[i]++;
}else{
if(ch == word1[i-1]){
dp[i] = dp_old[i-1];
}else{
dp[i] =1 + min(dp[i-1], min(dp_old[i], dp_old[i-1]));
}
}
}
}
return dp[n1];
}
};
仔细端详一维数组A, 假设一个2×2的矩阵,我们要计算右下角的值,只需要知道另外三个即可。
因此,这里,我们用一个lastPre来记住上次的,匹配了的值。
Mistakes:
当两个char 相等的时候,真是,没动脑,写成了A[j+1] = A[j] // 这样是错误的!!!!------------当递归调用不行的时候,直接就应该开始用DP--------------
用一个2D array 保存中间结果。
public class EditDistance {
public int minDistance(String word1, String word2) {
// use a matrix to record their simularities
int n1 = word1.length();
int n2 = word2.length();
int[][] minDist = new int[n1 + 1][n2 + 1];
// for minDist[i][j], i is the end index of word1(exclusive ) ,
// while j is the end index of work2( exclusive)
// STEP 1: fillin the edge when word1 is empty or word2 is empty
// at minDist[0][0] , both are empty, we need zero operation
for (int i = 0; i <= n1; i++) {
minDist[i][0] = i; // target word2 is empty, operation to given
// word[0...i] to word 2
}
for(int j =0;j<=n2;j++){
minDist[0][j] = j;// word1 is empty, number of operations to build word 2
}
for(int i =1; i<=n1;i++){
for(int j =1;j<=n2;j++){
if(word1.charAt(i-1) == word2.charAt(j-1)){
minDist[i][j] = minDist[i-1][j-1];
}else{
// delete the last of s1
int deleteLastWord1 = 1 + minDist[i-1][j];
// replace the last of word1 to the last of word2
int replaceLastWord1 = 1 + minDist[i-1][j-1];
// insert the last of word2 to the end of word1
int insertLastWord1 = 1 + minDist[i][j-1];
int tmp = Math.min(deleteLastWord1, replaceLastWord1);
minDist[i][j] = Math.min(tmp, insertLastWord1);
}
}
}
return minDist[n1][n2];
}
}
--------------------------------2 rd Pass---------------------------------------------------------------------------Rolling table----------------
基本的rolling table只需要知道上边和左边的操作就行了。(对应delete and insert)但这里还给了第三种操作:replace。这样就导致了不能直接用一个1D array了,需要用2个。
一个就是还用普通的rolling table,(基本更动也照常)
另一个记录上一次的值。(因此需要每次跑完一行之后,把其重新copy)
public class Solution {
public int minDistance(String word1, String word2) {
int n1 = word1.length(), n2 = word2.length();
if( n1 ==0 || n2 == 0)
return Math.max(n1, n2);
int A[] = new int[n2+1];//rolling table--> index j would be the number of chars in word2 used
int lastA[] = new int[n2+1];
for(int j=0;j<= n2;j++)//using zero characters in word 1
A[j] = j;
for(int i =0;i<n1;i++){
for(int j =0;j<= n2;j++)
lastA[j] = A[j]; // remember that in the last time( or last line), the A[j] value
for(int j = 0;j<= n2;j++)
if(j==0){
A[j] = i+1; // # of chars in word1 used,
}else{
if(word1.charAt(i)== word2.charAt(j-1))
A[j] = lastA[j-1];
else
A[j] = 1+ Math.min(lastA[j-1], Math.min(A[j],A[j-1])); // min(replace, min(insert, delete))
}
}
return A[n2];
}
}
这道题,即使是转化成longgest common substring, 也是上面的复杂度。
除非用suffix tree来找。--但是那样的话,建tree的空间,时间开销也要O(n*log(n))
Mistakes: (for the 2nd pass)
1: 刚开始的时候,觉得既然只需要记住lastA的话, 那么只用一个变量即可。 但那样可能会搞得比较复杂。想想为什么呢?
2: 每次update lastA的时候,都是放在for(int j ....)里面了,想那样写,多省几行, 哎, 多无謂的浪费阿~~~~
3: update lastA的时候, 虽然也是写了。但是放在了 upate A 之后, 这样是不对的,应该是放在之前。 (其实主要区别也就是在于 初始化 lastA的时候的值不一样)
Learned:
-------------递归方法---------考虑到重复计算的浪费, 因此也用了2D array来记录 中间结果-------
public class Solution {
public int minDistance(String word1, String word2) {
int A[][] = new int[word1.length()+1][word2.length()+1];
for(int i =0;i< word1.length()+1;i++)
Arrays.fill(A[i],-1000);
return helper(A,word1,word2);
}
private int helper(int[][] A, String word1, String word2){
int i = word1.length(), j = word2.length();
if(A[i][j] >= 0){
}else if(i==0 || j == 0){
A[i][j] = Math.max(i,j);
}else if(word1.charAt(0) == word2.charAt(0))
A[i][j] = helper(A,word1.substring(1), word2.substring(1));
else{
int replace = helper(A,word1.substring(1), word2.substring(1));
int delete = helper(A,word1.substring(1),word2);
int insert = helper(A,word1,word2.substring(1));
A[i][j] = 1+ Math.min(replace,Math.min(delete,insert));
}
return A[i][j];
}
}
No comments:
Post a Comment