标签:turn image width lin 分析 strlen 循环 空间复杂度 现在
题目描述:用最少的操作将字符串A转化成字符串B,其中操作包括三种。
(1)删除一个字符;
(2)插入一个字符;
(3)将一个字符改为另一个字符。
//输入 fxpimu xwrs //输出 5
此题用动态规划的做法,首先需要定义F(i,j),表示长度为i的字符串A 转化为长度为j的字符串B的编辑距离。 首先能够得到两种较特殊情况:
1、当i为0时,F(0,j) = j (表示长度为0的字符串A 增加j个字母变为字符串B)
2、当j为0时,F(i,0) = i (表示长度为i的字符串A 删除i个字母变为字符串B)
接着可以通过判断A中第i个元素和B中第j个元素是否相等进行分类:
1、当a[i]==b[j]时,则不需要任何操作就可以让这两个字母相等,此时F(i,j) = F(i-1,j-1).
2、当a[i]!=b[j]时,F(i,j) =min( F(i,j-1)+1 , F(i-1,j)+1 , F(i-1,j-1)+1)
将字符串A转化为字符串B分别有三种操作,上面min中的三个数分别对应三种操作时的编辑距离,取其中最小的来更新F(i,j)。
因此取三种操作的最小值来更新F(i,j).
定义一个二维数组dp[i][j],代表长度为i的A字符串转化为长度为j的字符串B的编辑距离,初始化为上述两种特殊情况,然后两层for
循环不断更新dp数组即可。最后输出dp[alen][blen]即可。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; char a[2000],b[2000]; int dp[2000][2000]; int main() { cin>>a>>b; int alen=strlen(a); int blen=strlen(b); for(int i=0;i<=alen;i++)dp[i][0]=i; //初始化特殊情况 for(int j=0;j<=blen;j++)dp[0][j]=j; for(int i=1;i<=alen;i++) for(int j=1;j<=blen;j++) { if(a[i-1]==b[j-1]) //A中第i个元素和B中第j个元素相等时 dp[i][j]=dp[i-1][j-1]; else dp[i][j]=min(min(dp[i][j-1],dp[i-1][j]),dp[i-1][j-1])+1;//取三种实现方法的最小的一种 } cout<<dp[alen][blen]<<endl; return 0; }
空间复杂度:该方法用到了一个二维数组记录结果,其中二维数组的大小取决于两个字符串的长度,若字符串A的长度为alen,
字符串B的长度为blen,空间复杂度为O(alen*blen)
时间复杂度:更新数组用到两层循环,循环次数也取决于字符串的长度,因此时间复杂度为O(alen*blen).
个人感觉动态规划做起来还是有点难,因为之前练习的并不多,现在和别人差的很大,很多题都要想很久,并不能想的很明白
通过练习也对动态规划有了一定的认识和理解,希望能够更进一步!
标签:turn image width lin 分析 strlen 循环 空间复杂度 现在
原文地址:https://www.cnblogs.com/LjwCarrot/p/9925306.html