leetcode72:编辑距离(动态规划)

leetcode72:编辑距离

  • 题目:给你两个单词 word1 和 word2, 请返回将 word1 转换成 word2 所使用的最少操作数 。

    你可以对一个单词进行如下三种操作:

    插入一个字符 删除一个字符 替换一个字符

  • 思路:

    • 使用双指针遍历两个单词;

    • 当两个单词指针指向的字符相同,则两个单词均指向下一个字符;

    • 当两个单词指针指向的字符不同,取进行删除、插入、替换任一种操作后的最优解。

解法1:

class Solution {
    //定义备忘录,解决重叠子问题
    int[][] meno;
    public int minDistance(String word1, String word2) {
        int n = word1.length();
        int m = word2.length();
        meno = new int[n][m];
        for(int[] row : meno){
            Arrays.fill(row,-1);
        }
​
        return dp(word1,n-1,word2,m-1);
​
        
​
    }
    public int dp(String word1,int i,String word2,int j){
        
        //base case 
        //遇到任何一个单词走完了,则返回未走完的单词的数组下标加1
        //对另一个单词进行插入或者删除 未走完单词的长度即(j+1或i+1) 个操作
        if(i==-1) return j+1;
        if(j==-1) return i+1;
        if(meno[i][j]!=-1){
            return meno[i][j];
        }
        //如果两个单词指向的字符相同,则两个单词均指向下一个字符
        if(word1.charAt(i)==word2.charAt(j)){
            meno[i][j] = dp(word1,i-1,word2,j-1);
        }else{
            //当两个单词指向的字符不同,取进行删除、插入、替换任一种操作后的最优解
            //此种操作存在重叠子问题,故使用备忘录数组解决
            meno[i][j] =  min(
                dp(word1,i-1,word2,j)+1,//删除操作
                dp(word1,i,word2,j-1)+1,//插入操作
                dp(word1,i-1,word2,j-1)+1//替换操作
            );
        }
​
        return meno[i][j];
    }
    public int min(int a,int b, int c){
        return Math.min(a,Math.min(b,c));
    }
}

解法2:

class Solution {
    //定义备忘录,解决重叠子问题
    int[][] meno;
    public int minDistance(String word1, String word2) {
        int n = word1.length();
        int m = word2.length();
        meno = new int[n+1][m+1];
        for(int[] row : meno){
            Arrays.fill(row,-1);
        }
​
        int[][] dp = new int[n+1][m+1];
​
       
        for(int i =1;i<=n;i++){
            dp[i][0]=i;
        }
        for(int i =1;i<=m;i++){
            dp[0][i] = i;
        }
        
        for(int i =1;i<=n;i++){
            for(int j =1 ;j<=m;j++){
                if(meno[i][j]!=-1){
                    dp[i][j]=meno[i][j];
                    continue;
                }
                if(word1.charAt(i-1)==word2.charAt(j-1)){
                    dp[i][j]=dp[i-1][j-1];
                    meno[i][j] = dp[i][j];
                }else{
                    dp[i][j]= min(
                        dp[i-1][j]+1,
                        dp[i][j-1]+1,
                        dp[i-1][j-1]+1
                    );
                    meno[i][j] = dp[i][j];
​
                }
            }
        }
​
        return dp[n][m];
​
        
​
    }
   
    public int min(int a,int b, int c){
        return Math.min(a,Math.min(b,c));
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值