【刷题1】LeetCode 72. 编辑距离 java题解

好难啊 字符串动态规划的好多题我都不会

标签
字符串
动态规划

题目

https://leetcode-cn.com/problems/edit-distance/
【刷题1】LeetCode 72. 编辑距离 java题解_第1张图片

分析

本质不同的操作实际上只有三种:
1.在单词 A 中插入一个字符;
2.在单词 B 中插入一个字符;
3.修改单词 A 的一个字符。

转化为子问题:
以A = horse,B = ros 作为例子,
1.在单词 A 中插入一个字符:如果我们知道 horse 到 ro 的编辑距离为 a,那么显然 horse 到 ros 的编辑距离不会超过 a + 1。这是因为我们可以在 a 次操作后将 horse 和 ro 变为相同的字符串,只需要额外的 1 次操作,在单词 A 的末尾添加字符 s,就能在 a + 1 次操作后将 horse 和 ro 变为相同的字符串;
2.在单词 B 中插入一个字符:如果我们知道 hors 到 ros 的编辑距离为 b,那么显然 horse 到 ros 的编辑距离不会超过 b + 1,原因同上;
3.修改单词 A 的一个字符:如果我们知道 hors 到 ro 的编辑距离为 c,那么显然 horse 到 ros 的编辑距离不会超过 c + 1,原因同上。
那么,从 horse 变成 ros 的编辑距离应该为 min(a + 1, b + 1, c + 1)。
在这里插入图片描述
继续拆分,直到:
1.字符串 A 为空,如从 转换到 ro,显然编辑距离为字符串 B 的长度,这里是 2;
2.字符串 B 为空,如从 horse 转换到 ,显然编辑距离为字符串 A 的长度,这里是 5。

复杂度

时间复杂度 :O(mn),其中 m 为 word1 的长度,n 为 word2 的长度。
空间复杂度 :O(mn),我们需要大小为O(mn) 的 D 数组来记录状态值。

代码

用dp[m][n]表示,长为m的字符串A,和长为n的字符串B,的编辑距离。
在这里插入图片描述

class Solution {
    public int minDistance(String word1, String word2) {
        int m=word1.length();
        int n=word2.length();
        //都为空串
        if(m==0&&n==0)
            return 0;
        //有一个为空串
        if(m==0||n==0)
            return m+n;
        int[][] dp=new int[m+1][n+1];
        dp[0][0]=0;
        //字符串B为空,编辑距离就是字符串A长度
        for(int i=1;i<=m;i++){
            dp[i][0]=i;
        }
        //字符串A为空,编辑距离就是字符串B长度
        for(int i=1;i<=n;i++){
            dp[0][i]=i;
        }
        for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++){
                int a=dp[i-1][j];//在A末尾插入一个字符
                int b=dp[i][j-1];//在B末尾插入一个字符
                int c=dp[i-1][j-1];//
                if(word1.charAt(i-1)!=word2.charAt(j-1)){
                    c+=1;
                }
                dp[i][j]=Math.min(Math.min(a+1,b+1),c);
            }
        }
        return dp[m][n];
    }
}

结果

【刷题1】LeetCode 72. 编辑距离 java题解_第2张图片

你可能感兴趣的:(LeetCode,字符串,java,leetcode,算法,动态规划)