LeetCode OJ 之 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

给两个单词word1和word2,找出从word1转化为word2需要的最小步骤个数。下面的每个操作代表一步。

在一个单词上可以有下面三种操作:

a、插入一个字符

b、删除一个字符

c、代替一个字符

思路:

动态规划法:设状态为f[i][j] ,表示A[0,i-1] 和B[0,j-1] 之间的最小编辑距离。设A[0,i-1] 的形式是str1c,B[0,j-1] 的形式是str2d,
1. 如果 c==d,则f[i][j]=f[i-1][j-1] ;
2. 如果 c!=d,
(a) 如果将c 替换成d,则f[i][j]=f[i-1][j-1]+1;
(b) 如果在c 后面添加一个d,则f[i][j]=f[i][j-1]+1;
(c) 如果将c 删除,则f[i][j]=f[i-1][j]+1;

代码:

class Solution {
public:
    int minDistance(string word1, string word2) 
    {
        int len1 = word1.size();
        int len2 = word2.size();
        vector<vector<int> > f(len1+1,vector<int>(len2+1,0));
        for(int i = 0 ; i <= len1 ; i++)
            f[i][0] = i;
        for(int j = 0 ; j <= len2 ; j++)
            f[0][j] = j;
        for(int i = 1 ; i <= len1 ; i++)
        {
            for(int j = 1 ; j <= len2 ;j++)
            {
                if(word1[i-1] == word2[j-1])
                    f[i][j] = f[i-1][j-1];
                else
                {
                    int tmp = min(f[i-1][j] , f[i][j-1]);
                    f[i][j] = 1 + min(tmp , f[i-1][j-1]);
                }
            }
        }
        return f[len1][len2];
    }
};
用一维数组优化存储空间:
class Solution {
public:
    int minDistance(string word1, string word2) 
    {
        int len1 = word1.size();
        int len2 = word2.size();
        if(len1 == 0 && len2 == 0)
            return 0;
        if(len1 < len2)
            return minDistance(word2 , word1);//保证word2较短
        vector<int> f(len2+1 , 0);
        for(int i = 0 ; i <= len2 ; i++)
            f[i] = i;
        int pre = 0 ;额外用一个变量记录f[i-1][j-1]  
        int tmp = 0;
        for(int j = 1 ; j <= len1 ; j++)
        {
            pre = f[0];//把上次的f[0]保存下来
            f[0] = j;
            for(int k = 1 ; k <= len2 ; k++)
            {
                tmp = f[k];//把上次的f[k]临时保存下来,以便下面赋给pre
                if(word1[j-1] == word2[k-1])    //注意f[k]求的是0~k-1的字符的变化情况
                    f[k] = pre;     
                else
                {
                    f[k] = min(f[k-1] , min(f[k] , pre)) + 1;
                }
                pre = tmp;//把上次的f[k]保存到pre中,以便下次比较
            }
        }
        return f[len2];
    }
};




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值