【LeetCode】72. Edit Distance

问题描述

https://leetcode.com/problems/edit-distance/#/description

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

word1变为word2,可以有三种操作,删除、替换、增加一个字符,每执行一次算作一次操作,返回至少需要多少次操作。

算法

使用动态规划,设f(i,j)表示将word1的前i个字符转化为word2的前j个字符,设n=word1.length(), m=word2.length(),则最终的结果就是求:f(n, m)

下面是动态转移方程:

  1. 初始条件,f(0,k) = f(k,0) = kf(0,k)=k表示将word1的前0个字符转换为word2的前k个字符所需操作数,因为是从0个字符变换为k个字符,自然需要k次操作
  2. word1[i] = word2[j]时,有f(i,j) = f(i-1,j-1),因为此时不需要操作,所以操作次数与前面的变换次数相等
  3. word2[i] != word2[j]时,有f(i,j) = 1 + min{f(i,j-1), f(i-1,j), f(i-1,j-1)}f(i,j-1)表示insert, f(i-1,j)表示deletef(i-1,j-1)表示replace

时间复杂度O(nm)

代码

    public class Solution {

        /**
         * 将word1变为word2,可以有三种操作,删除、替换、增加一个字符,每执行一次算作一次操作,返回至少需要多少次操作。
         * 算法:
         * 使用动态规划,设f(i,j)表示将word1的前i个字符转化为word2的前j个字符,设n=word1.length(), m=word2.length(),则最终的结果就是求:f(n, m)
         * 下面是动态转移方程:
         * 1. 初始条件,f(0,k) = f(k,0) = k,f(0,k)=k表示将word1的前0个字符转换为word2的前k个字符所需操作数,因为是从0个字符变换为k个字符,自然需要k次操作
         * 2. word1[i] = word2[j]时,有f(i,j) = f(i-1,j-1),因为此时不需要操作,所以操作次数与前面的变换次数相等
         * 3. word2[i] != word2[j]时,有f(i,j) = 1 + min{f(i,j-1), f(i-1,j), f(i-1,j-1)},f(i,j-1)表示insert, f(i-1,j)表示delete,f(i-1,j-1)表示replace
         */
        public int minDistance(String word1, String word2) {
            int n = word1.length();
            int m = word2.length();

            int[][] f = new int[n+1][m+1];
            for(int i=0;i<=m;i++) {
                f[0][i] = i;
            }
            for(int i=0;i<=n;i++) {
                f[i][0] = i;
            }
            for(int i=1;i<=n;i++) {
                for(int j=1;j<=m;j++) {
                    if(word1.charAt(i-1) == word2.charAt(j-1)) {
                        f[i][j] = f[i-1][j-1];
                    } else {
                        f[i][j] = 1 + Math.min(f[i][j-1], Math.min(f[i-1][j], f[i-1][j-1]));
                    }
                }
            }
            return f[n][m];
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值