【Edit Distance】cpp
题目:
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
代码:
class Solution { public: int minDistance(string word1, string word2) { const int n1 = word1.size(); const int n2 = word2.size(); // initialization vector<vector<int> > dp(n1+1,vector<int>(n2+1,0)); dp[0][0] = 0; for ( int j=1; j<=n2; ++j ) dp[0][j] = dp[0][j-1]+1; for ( int i=1; i<=n1; ++i ) dp[i][0] = dp[i-1][0]+1; // dp process for ( int i=1; i<=n1; ++i ) { for ( int j=1; j<=n2; ++j ) { if ( word1[i-1]==word2[j-1] ) { dp[i][j] = dp[i-1][j-1]; } else { int rep = dp[i-1][j-1] + 1; // replace int del = dp[i-1][j] + 1; // delete int ins = dp[i][j-1] + 1; // insert dp[i][j] = std::min(rep,std::min(del, ins)); } } } return dp[n1][n2]; } };
tips:
不知道这是一个经典的DP案例,确实首次感到DP算法挺精妙的,很多无法想清楚理清楚的事情,交给DP就好了。
参考了两个网上blog的解释:
http://fisherlei.blogspot.sg/2012/12/leetcode-edit-distance.html
http://bangbingsyb.blogspot.sg/2014/11/leetcode-edit-distance.html
dp[i][j]表示s1[0~i-1]与s2[0~j-1]的编辑距离:
根据题意,计算dp[i][j]分如下几种情况:
1. 如果s1[i-1]==s2[j-1] 则不用三种操作,直接dp[i][j] = dp[i-1][j-1]
2. 如果s1[i-1]!=s2[j-1] 则需要在上几步的基础上进行匹配操作:
a) 如果直接选择替换则 dp[i][j] = dp[i-1][j-1] + 1
翻译过来就是:s1[0~i-2]与s2[0~j-2]已经对上了,把s1[i-1]的值换成s2[j-1]的值,替换之;
b) 如果选择删除操作则 dp[i][j] = dp[i-1][j] + 1
翻译过来就是:s1[0~i-2]与s2[0~j-1]已经对上了,这个s1[i-1]就是多余的了,删除之;
c) 如果选择插入操作则 dp[i][j] = dp[i][j-1] + 1
翻译过来就是:s1[0~i-1]与s2[0~j-2]已经对上了,因此少s1当前坐标后面再不上一个s2[j-1]这个值就OK了,插入之;
按照上述的过程,就可以写出来代码了。
为什么每次都加1呢?因为字符要一个一个匹配。
“插入”、“替换”、“删除”什么时候出现是有讲究的。最优的情况就是这些操作单独就可以完成转换,所以要选择出现的情况。
=============================================
第二次过这道题,一开始忘记了word1[i-1]==word2[j-1]的情况,改了之后AC了。
class Solution { public: int minDistance(string word1, string word2) { if ( word1==word2 ) return 0; int dp[word1.size()+1][word2.size()+2]; fill_n(&dp[0][0], (word1.size()+1)*(word2.size()+1), 0); for ( int i=1; i<=word1.size(); ++i ) dp[i][0] = dp[i-1][0]+1; for ( int i=1; i<=word2.size(); ++i ) dp[0][i] = dp[0][i-1]+1; // dp process for ( int i=1; i<=word1.size(); ++i ) { for ( int j=1; j<=word2.size(); ++j ) { if ( word1[i-1]==word2[j-1] ) { dp[i][j] = dp[i-1][j-1]; continue; } // insert int ins = dp[i][j-1]+1; // delete int del = dp[i-1][j]+1; // replace int rep = dp[i-1][j-1]+1; dp[i][j] = min(ins,min(del,rep)); } } return dp[word1.size()][word2.size()]; } };
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?