【Leetcode】72. 编辑距离

96 阅读2分钟

题目描述

在这里插入图片描述

// 72. 编辑距离

// 给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的
// 最少操作数 。

// 你可以对一个单词进行如下三种操作:
// 插入一个字符
// 删除一个字符
// 替换一个字符

题解

// 动态规划
// 取word1长度记为n,取word2长度记为m
// 如果len1或者len2出现了0,相乘必为0,返回len1+len2即可,
// 说明假设len2为0,word1就需要一直删len1次才能转换为word2,
// 假设len1为0,word1就需要一直插入len2次才能转换为word2。
// 
// 构建动态规划矩阵dp,dp[i][j]表示word1中的字符变换到word2中的字符需要的
// 最少操作次数。先初始化第0行和第0列,
// for循环遍历第一列(j=0),遍历索引元素为dp[i][0],等于前一位操作次数累加1,
// for循环遍历第一行(i=0),遍历索引元素为dp[0][j],等于前一位操作次数累加1。

// 初始化之后,从dp[1][1]开始双循环遍历,遍历索引元素为dp[i][j],
// dp[i][j]的操作次数可能是由插入字符,删除字符或者替换字符得到的。
// 其中dp[i - 1][j]和dp[i][j - 1]分别表示插入字符和删除字符操作的位置。
// dp[i - 1][j]+1记为delet,dp[i][j - 1]+1记为insert,
// 这样累加一次就得到了操作之后的次数。 dp[i - 1][j - 1]记为replace,
// 表示替换字符位置,判断word1的i-1位置是否和word2的j-1位置不相等,
// 如果不相等的话replace累加一次。之后取delete,insert和replace中的最小值
// (最小操作次数)赋给dp[i][j]。
// 如此循环,最后返回dp[len1][len2]即可。
// 
// 执行用时:7 ms, 在所有 Java 提交中击败了41.61%的用户
// 内存消耗:38.8 MB, 在所有 Java 提交中击败了9.19%的用户
class Solution {
    public int minDistance(String word1, String word2) {
		int len1 = word1.length();
		int len2 = word2.length();
		if (len1 * len2 == 0) return len1 + len2;
		
		int i, j;
		int[][] dp = new int[len1 + 1][len2 + 1];
		for (i = 1; i < len1 + 1; i++) {
			dp[i][0] = dp[i - 1][0] + 1;
		}
		for (j = 1; j < len2 + 1; j++) {
			dp[0][j] = dp[0][j - 1] + 1;
		}
		for (i = 1; i < len1 + 1; i++) {
			for (j = 1; j < len2 + 1; j++) {
				int delete = dp[i - 1][j] + 1;
				int insert = dp[i][j - 1] + 1;
				int replace = dp[i - 1][j - 1];
				if (word1.charAt(i - 1) != word2.charAt(j - 1))
					replace += 1;
				dp[i][j] = Math.min(delete, Math.min(insert, replace));
			}
		}
		return dp[len1][len2];
    }
}