LeetCode | Edit Distance

question:

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

explanation:

Let following be the function definition :-

f(i, j) := minimum cost (or steps) required to convert first i characters of word1 to first j characters of word2

Case 1: word1[i] == word2[j], i.e. the ith the jth character matches.

f(i, j) = f(i - 1, j - 1)
Case 2: word1[i] != word2[j], then we must either insert, delete or replace, whichever is cheaper

f(i, j) = 1 + min { f(i, j - 1), f(i - 1, j), f(i - 1, j - 1) }
f(i, j - 1) represents insert operation
f(i - 1, j) represents delete operation
f(i - 1, j - 1) represents replace operation
Here, we consider any operation from word1 to word2. It means, when we say insert operation, we insert a new character after word1 that matches the jth character of word2. So, now have to match i characters of word1 to j - 1 characters of word2. Same goes for other 2 operations as well.

Note that the problem is symmetric. The insert operation in one direction (i.e. from word1 to word2) is same as delete operation in other. So, we could choose any direction.

Above equations become the recursive definitions for DP.

Base Case:

f(0, k) = f(k, 0) = k
Below is the direct bottom-up translation of this recurrent relation. It is only important to take care of 0-based index with actual code :-

solution

normal solution:

public int minDistance(String word1, String word2) {

    int [][]m=new int[word1.length()+2][word2.length()+2];
    // 0 :match 1: insert 2:delete
    int []opt=new int[3];

    for(int i=0;i<=word1.length();i++)
    {
        m[i][0]=i;
    }

    for(int j=0;j<=word2.length();j++)
    {
        m[0][j]=j;
    }

    for(int i=1;i<=word1.length();i++)
        for(int j=1;j<=word2.length();j++)
        {
            opt[0]=m[i-1][j-1]+match(word1.charAt(i-1),word2.charAt(j-1));
            opt[1]=m[i-1][j]+1;
            opt[2]=m[i][j-1]+1;
            m[i][j]=Math.min(Math.min(opt[0],opt[1]),opt[2]);
            //System.out.println(opt[0]+" "+opt[1]+" "+opt[2]);
        }

    return m[word1.length()][word2.length()];
}

int match(char a ,char b)
{
    if(a==b)
    {
        return 0;
    }
    return 1;
}

a better solution:

public class Solution {
public int minDistance(String word1, String word2) {
    int m = word1.length();
    int n = word2.length();

    int[][] cost = new int[m + 1][n + 1];
    for(int i = 0; i <= m; i++)
        cost[i][0] = i;
    for(int i = 1; i <= n; i++)
        cost[0][i] = i;

    for(int i = 0; i < m; i++) {
        for(int j = 0; j < n; j++) {
            if(word1.charAt(i) == word2.charAt(j))
                cost[i + 1][j + 1] = cost[i][j];
            else {
                int a = cost[i][j];
                int b = cost[i][j + 1];
                int c = cost[i + 1][j];
                cost[i + 1][j + 1] = a < b ? (a < c ? a : c) : (b < c ? b : c);
                cost[i + 1][j + 1]++;
            }
        }
    }
    return cost[m][n];
}
}

Time complexity : If n is the length of word1, m of word2, because of the two indented loops, it is O(nm)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值