leetcode 72. Edit Distance
一、问题描述
给定两个单词word1和word2,找到将word1转换为word2所需的最少操作次数。
对于某个单词,可以有以下3个操作:
1)插入一个字符
2)删除一个字符
3)替换一个字符
【举例】
例1:
输入: word1 = "horse", word2 = "ros"
输出: 3
解释:
horse -> rorse (replace 'h' with 'r')
rorse -> rose (remove 'r')
rose -> ros (remove 'e')
例2:
输入: word1 = "intention", word2 = "execution"
输出: 5
解释:
intention -> inention (remove 't')
inention -> enention (replace 'i' with 'e')
enention -> exention (replace 'n' with 'x')
exention -> exection (replace 'n' with 'c')
exection -> execution (insert 'u')
二、解题思路
解题思路:--- 字符串对齐思路
word1【源串】 : h o r s e
word2【目标串】: r o s e r
设dp[i][j]为word1长度为i的子串,到word2长度为j的子串的最小编辑距离
三种情境:
- word1当前字符为ch1,word2当前字符为空(如上第3个字符 r <--> ''),则源串word1删除ch1:dp[i-1][j]+1
- word1当前字符为空,word2当前字符为ch2(如上最后一个字符 '' <--> r),则源串word1插入ch2:dp[i][j-1]+1
- word1当前字符为ch1,word2当前字符为ch2(如上第1个字符), 若ch1==ch2,则继承dp[i-1][j-1]的值;若ch1!=ch2,则源串ch1替换成ch2:dp[i-1][j-1]+1
总结成状态转移方程:
边界:
- dp[i][0]=i
- dp[0][j]=j
dp[i][j] = min (
- dp[i-1][j]+1 //word1[i]不在word2[0,,,j]中---删除操作
- dp[i][j-1]+1 //word1[i]在word2[0,,,j-1]中---插入操作
- dp[i-1][j-1]+0/1 //word1[i]在word2[j] -- 相等取0,不相等则替换操作 )
补充---一般化理解:
四种情况(S为源串,即待变化的串;T为目标串,即参考串)
1)S为字符 <----> T为字符:
- 相等:dp[i][j] = dp[i-1][j-1]
- 不相等:dp[i][j] = dp[i-1][j-1] + 1
2)S为字符 <----> T为空(删除操作):
- dp[i][j] = dp[i-1][j] + 1
3)S为空 <----> T为字符(插入操作):
- dp[i][j] = dp[i][j-1] + 1
4)S为空 <----> T为空(无效操作)
转换成数学表达式:dp[i][j] = min(dp[i-1][j]+1, dp[i][j-1]+1, dp[i-1][j-1]+(S[i]==T[j]?0:1))
即:
dp[i][j] = dp[i-1][j-1] S[i] == T[j]
dp[i][j] = min(dp[i-1][j] , dp[i][j-1] , dp[i-1][j-1]) + 1 S[i] != T[j]
三、解题算法
/***************************************************
Author:tmw
date:2018-5-27
****************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define min(a,b) (a<b?a:b)
int minDistance(char* word1, char* word2)
{
int len1 = strlen(word1);
int len2 = strlen(word2);
int i,j;
int dp[len1+1][len2+1];
//初始化边界
for(i=0; i<=len1; i++)
dp[i][0] = i;
for(j=0; j<=len2; j++)
dp[0][j] = j;
//填充其他状态
for(i=1; i<=len1; i++)
{
for(j=1; j<=len2; j++)
{
if( word1[i-1] == word2[j-1] )
dp[i][j] = dp[i-1][j-1];
else
{
int temp = min(dp[i-1][j], dp[i][j-1]);
dp[i][j] = min(temp,dp[i-1][j-1])+1;
}
}
}
return dp[len1][len2];
}
四、执行结果
leetcode accept
梦想还是要有的,万一实现了呢~~~~ヾ(◍°∇°◍)ノ゙~~~