题目:

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+,vector<int>(n2+,));
dp[][] = ;
for ( int j=; j<=n2; ++j ) dp[][j] = dp[][j-]+;
for ( int i=; i<=n1; ++i ) dp[i][] = dp[i-][]+;
// dp process
for ( int i=; i<=n1; ++i )
{
for ( int j=; j<=n2; ++j )
{
if ( word1[i-]==word2[j-] )
{
dp[i][j] = dp[i-][j-];
}
else
{
int rep = dp[i-][j-] + ; // replace
int del = dp[i-][j] + ; // delete
int ins = dp[i][j-] + ; // 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 ;
int dp[word1.size()+][word2.size()+];
fill_n(&dp[][], (word1.size()+)*(word2.size()+), );
for ( int i=; i<=word1.size(); ++i ) dp[i][] = dp[i-][]+;
for ( int i=; i<=word2.size(); ++i ) dp[][i] = dp[][i-]+;
// dp process
for ( int i=; i<=word1.size(); ++i )
{
for ( int j=; j<=word2.size(); ++j )
{
if ( word1[i-]==word2[j-] )
{
dp[i][j] = dp[i-][j-];
continue;
}
// insert
int ins = dp[i][j-]+;
// delete
int del = dp[i-][j]+;
// replace
int rep = dp[i-][j-]+;
dp[i][j] = min(ins,min(del,rep));
}
}
return dp[word1.size()][word2.size()];
}
};

【Edit Distance】cpp的更多相关文章

  1. [USACO 2012 Mar Silver] Landscaping【Edit Distance】

    传送门:http://www.usaco.org/index.php?page=viewproblem2&cpid=126 好题啊好题,一开始就输给了这道题的想法! 先把原始状态以及目标状态换 ...

  2. hdu 4739【位运算】.cpp

    题意: 给出n个地雷所在位置,正好能够组成正方形的地雷就可以拿走..为了简化题目,只考虑平行于横轴的正方形.. 问最多可以拿走多少个正方形.. 思路: 先找出可以组成正方形的地雷组合cnt个.. 然后 ...

  3. Hdu 4734 【数位DP】.cpp

    题意: 我们定义十进制数x的权值为f(x) = a(n)*2^(n-1)+a(n-1)*2(n-2)+...a(2)*2+a(1)*1,a(i)表示十进制数x中第i位的数字. 题目给出a,b,求出0~ ...

  4. 【Valid Sudoku】cpp

    题目: Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could ...

  5. 【Remove Elements】cpp

    题目: Given an array and a value, remove all instances of that value in place and return the new lengt ...

  6. 【Permutations II】cpp

    题目: Given a collection of numbers that might contain duplicates, return all possible unique permutat ...

  7. 【Subsets II】cpp

    题目: Given a collection of integers that might contain duplicates, nums, return all possible subsets. ...

  8. 【Sort Colors】cpp

    题目: Given an array with n objects colored red, white or blue, sort them so that objects of the same ...

  9. 【Sort List】cpp

    题目: Sort a linked list in O(n log n) time using constant space complexity. 代码: /** * Definition for ...

随机推荐

  1. 原生ajax瀑布流demo

    最近听朋友们说起瀑布流挺多的,自己就去研究下了,一个简单的原生demo,分享给大家... 简单分为三个文档,有详细的注释:img:ajax.php:demo.php 其中img文件夹中放入图片 1.j ...

  2. EPSG:4326

    简单说,"EPSG:4326"指的就是WGS84坐标系 参考 http://blog.csdn.net/cloverwindy/article/details/8663968 AU ...

  3. FMCW 雷达原理(转)

    FMCW(Frequency Modulated Continuous Wave),即调频连续波.FMCW技术和脉冲雷达技术是两种在高精度雷达测距中使用的技术.其基本原理为,发射波为高频连续波,其频率 ...

  4. 构建第一个spring boot2.0应用之项目启动运行的几种方式(二)

    方法一. 配置Run/Debug Configuration  选择Main Class为项目 Application启动类(入口main方法) (2).进行项目目录,即包含pom.xml的目录下,启 ...

  5. git push 使用教程

    git push命令用于将本地分支的更新,推送到远程主机.它的格式与git pull命令相仿. $ git push <远程主机名> <本地分支名>:<远程分支名> ...

  6. MeshLab中插件的添加过程

    MeshLab中主要插件类型有 filter plugins, i/o plugins, edit plugins,这些插件实现了MeshLab的大部分功能.新加入的插件命名规则最好也遵循规范,可命名 ...

  7. JFinal常量配置学习笔记

    在继承 JFinalConfig 类时,需要 实现 /** * Config constant */ public abstract void configConstant(Constants me) ...

  8. spark集群配置细则总结

    修改目录与目录组: sudo chown -R hadoop:hadoop spark-1.6.1-bin-hadoop2.6 sudo chown -R hadoop:hadoop jdk1.8.0 ...

  9. 兼容ie8的圆形进度条

    主要是利用html5中的svg 画出圆形进度条 并且兼容ie8 https://github.com/GainLoss/Circular-progress-bar

  10. 父子组件通信(vuex的方式)

    转: https://blog.csdn.net/lzh5997/article/details/80407518 父子组件也可以通过vuex的进行来进行中转,其实vuex就类似与一个仓库,父组件把东 ...