(LeetCode 72)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

题目:

给定两个字符串,求把S变成T所需的最小操作数。

3种字符操作分别为插入、删除、替换。

思路:

动态规划思想:

假设dp[i][j]表示以S[i]结尾的字符串和以T[j]结尾的字符串转换所需的最小操作数,考虑三种操作,然后取三者最小值:

1、替换:

假设S[i-1],T[j-1]已对齐,即dp[i-1][j-1]已知,则当S[i]==T[j]时,dp[i][j]=dp[i-1][j-1],否则,dp[i][j]=dp[i-1][j-1]+1.

2、删除

假设S[i-1],T[j]已对齐,即dp[i-1][j]已知,多出来的S[i]需删除,操作数+1,则dp[i][j]=dp[i-1][j]+1.

3、插入

假设S[i],T[j-1]已对齐,即dp[i][j-1]已知,需在S中插入S[i+1]=T[j]来匹配,操作数+1,则dp[i][j]=dp[i][j-1]+1.

状态转移方程:

dp[i][j]=min(dp[i-1][j-1]+(S[i]==T[j]?0,1),dp[i-1][j]+1,dp[i][j-1]+1)

初始值:

dp[i][0]=i

dp[0][j]=j

复杂度:

时间复杂度:O(m*n)

空间复杂度:O(m*n)

空间优化:

由状态转移方程可知,dp[i][j]与dp[i-1][j-1],dp[i-1][j],dp[i][j-1]有关,可以去掉一维,只留下dp[j]。

等式右边的dp[i-1][j]和dp[i][j-1]都可以直接改成dp[j](旧的值)和dp[j-1](已更新),只有dp[i-1][j-1]没有记录下来,通过某个变量保存起来之后就可以。

因此空间复杂度:O(n)

代码:

class Solution {
public:
    int minDistance(string word1, string word2) {
        int m=word1.length();
        int n=word2.length();
        vector<vector<int> > distance(m+1,vector<int>(n+1));
        
        for(int i=0;i<=m;i++){
            for(int j=0;j<=n;j++){
                if(0==i){
                    distance[i][j]=j;
                }
                else if(0==j){
                    distance[i][j]=i;
                }
                else{
                    distance[i][j]=min(distance[i-1][j-1]+((word1[i-1]==word2[j-1])?0:1),
                                       min(distance[i-1][j]+1,distance[i][j-1]+1)
                                       );
                }   
            }        
        }
        return distance[m][n];
    }
};
class Solution {
public:
    int minDistance(string word1, string word2) {
        int m=word1.length();
        int n=word2.length();
        vector<int> distance(n+1);
        
        for(int i=0;i<=m;i++){
            int last;
            for(int j=0;j<=n;j++){
                if(0==i){
                    distance[j]=j;
                }
                else if(0==j){
                    last=distance[j];
                    distance[j]=i;
                }
                else{
                    int temp=distance[j];
                    distance[j]=min(last+((word1[i-1]==word2[j-1])?0:1),
                                       min(distance[j]+1,distance[j-1]+1)
                                       );
                    last=temp;
                }   
            }        
        }
        return distance[n];
    }
};

  

    原文作者:AndyJee
    原文地址: https://www.cnblogs.com/AndyJee/p/4602817.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞