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];
        }
    };
    

      

  • 相关阅读:
    [NHibernate]第一个NHibernate的应用配置
    [NHibernate]利用LINQPad查看NHibernate生成SQL语句
    [NHibernate]查看NHibernate生成的SQL语句
    Twitter的分布式自增ID雪花算法snowflake (Java版)
    雪花算法:生成分布式全局唯一ID
    数据加密共享与签名方案
    Java 8中处理集合的优雅姿势——Stream
    消息中间件选型分析——从Kafka与RabbitMQ的对比来看全局
    从概念到底层技术,一文看懂区块链架构设计(附知识图谱)
    以太坊源码分析——BlockChain
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4602817.html
Copyright © 2011-2022 走看看