[LeetCode#72]Edit Distance

本文详细解析了编辑距离问题,通过动态规划方法高效地解决了两个字符串之间的转换步骤问题。介绍了插入、删除和替换字符三种操作,并提供了实现代码。

Problem:

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

Analysis:

This problem is very ticky and easy!!!
Reference: https://en.wikipedia.org/wiki/Edit_distance

For String problem, if we were asked to compare to string according to order, this problem could and should always be efficiently sovled by dynamic programming method. If the problem allow the string to be permutated, we should take care, since it usually should be solved through HashMap way.

Idea:
Assume you have a dist array, dist[i+1][j+1] means the distance between word1[0, i] and word2[0, j]. You should try to use the proper transitional function to reach the answer dist[word1.length][word2.length].
Note: for this problem dist[0][0] is for empty string "" "". 

Transitional functions:
1. iff word1[i] == word2[j], dist[i+1][j+1] = dist[i][j].
if (word1.charAt(i-1) == word2.charAt(j-1)) {
    dist[i][j] = dist[i-1][j-1];
}
2. iff word1[i] != word2[j], the following ways could be used:
    2.1 subsitute word1[i] with the same character of word2[j], dist[i+1][j+1] = dist[i][j] + 1.
    2.2 add word1[i] into word2, dist[i+1][j+1] = dist[i][j+1] + 1(word1[i] == added)
    2.3 add word1[j] into word2, the same as above. 
    
if (word1.charAt(i-1) == word2.charAt(j-1)) {
    ...
} else{
    int sub = dist[i-1][j-1] + 1;
    int add_a = dist[i-1][j] + 1;
    int add_b = dist[i][j-1] + 1;
    dist[i][j] = Math.min(sub, Math.min(add_a, add_b));
}


Skills:
1. Why don't we consider the method of delete?
Delete a character from one string is equal to add a character into one string, both of them need one extra operation. 
To add a character into a string, 
To delete a word from word2, dist[i][j] = dist[i][j-1] + 1;
Thus we have no need to consider the case of deleting a character. 

2. Since the transitional function use dist[i-1][j-1], dist[i-1][j] and dist[i][j-1], to avoid corner cases, we should take advatage of empty string. (which help to keep invariance right and code simple!). But you should take care the change in indexing. the i is equeal to i-1 in word's indexing system.

int[][] dist = new int[m+1][n+1];
for (int i = 0; i <= m; i++)
    dist[i][0] = i;
for (int j = 0; j <= n; j++)
    dist[0][j] = j;
0    | 1 2 3 . . . 
---  |------------
 1   |
 2   |
 3   |
 .   |
 .   |
Key: you must initate the right value for additional row and column.

Solution:

public class Solution {
    public int minDistance(String word1, String word2) {
        if (word1 == null || word2 == null)
            return 0;
        int m = word1.length();
        int n = word2.length();
        int[][] dist = new int[m+1][n+1];
        for (int i = 0; i <= m; i++)
            dist[i][0] = i;
        for (int j = 0; j <= n; j++)
            dist[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)) {
                    dist[i][j] = dist[i-1][j-1];
                } else{
                    int sub = dist[i-1][j-1] + 1;
                    int add_a = dist[i-1][j] + 1;
                    int add_b = dist[i][j-1] + 1;
                    dist[i][j] = Math.min(sub, Math.min(add_a, add_b));
                }
            }
        }
        return dist[m][n];
    }
}

 

转载于:https://www.cnblogs.com/airwindow/p/4762951.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值