zoukankan      html  css  js  c++  java
  • (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];
        }
    };
    

      

  • 相关阅读:
    RMAN详细教程(三):备份脚本的组件和注释
    RMAN详细教程(二):备份、检查、维护、恢复
    RMAN详细教程(一):基本命令代码
    centos6和centos7的防火墙基本命令
    如何在Centos服务器上搭建起Oracle10、VNC、以及FTP
    添加Chrome插件时出现“程序包无效”等问题的解决办法
    配置服务器的磁盘阵列并正确分区
    配置VNC并远程控制服务器(电脑)
    .Net之路(十五)图解LoadRunner压力测试
    Mysql免安装版安装配置及常用操作
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4602817.html
Copyright © 2011-2022 走看看