首页 > 代码库 > 由LCS到编辑距离—动态规划入门—算法学习笔记

由LCS到编辑距离—动态规划入门—算法学习笔记

一切计算机问题,解决方法可以归结为两类:分治和封装。分治是减层,封装是加层。

动态规划问题同样可以用这种思路,分治。

它可以划分为多个子问题解决,那这样是不是用简单的递归就完成了?也许是的,但是这样会涉及太多的不便的操作。因为子问题有重叠!

针对这种子问题有重叠的情况的解决,就是提高效率的关键。

所以动态规划问题可以总结为:最优子结构和重叠子问题。

解决这个子问题的方式的关键就是:memoization,备忘录。

动态规划算法分以下4个步骤:

  1. 描述最优解的结构
  2. 递归定义最优解的值
  3. 按自底向上的方式计算最优解的值   //此3步构成动态规划解的基础。
  4. 由计算出的结果构造一个最优解。   //此步如果只要求计算最优解的值时,可省略。

现在举一个具体例子来看:LCS

LCS问题即最长公共子序列问题,它要求所求得的字符在所给的字符串中是连续的(例如:输入两个字符串BDCABA和ABCBDAB,字符串BCBA和BDAB都是是它们的最长公共子序列,则输出它们的长度4,并打印任意一个子序列)。

动态规划思想:BDCABA和ABCBDAB的LCS等于BDCAB和ABCBDAB的LCS,和BDCABA和ABCBDA的LCS中大的值。

设计个函数子串一为X(n),子串二为Y(m),他们俩的LCS为L(X(n),Y(m))。将上面的文字转为函数:

L(X(n),Y(m))=max(L(X(n-1),Y(m)),L(X(n),Y(m-1)));

看出子问题的结构了吧,下图更简单:

看到第一行和第一列都是0了吗?思考一下为什么

再看一个题:Edit Distance:

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

a.首先是有两个字符串,这里写一个简单的 abc和abe

b.将字符串想象成下面的结构。

A处 是一个标记,为了方便讲解,不是这个表的内容。

 

  abc a b c
abe 0 1 2 3
a 1 A处    
b 2      
e 3      

c.来计算A处 出得值

它的值取决于:左边的1、上边的1、左上角的0.

按照Levenshtein distance的意思:

上面的值和左面的值都要求加1,这样得到1+1=2。

A处 由于是两个a相同,左上角的值加0.这样得到0+0=0。

这是后有三个值,左边的计算后为2,上边的计算后为2,左上角的计算为0,所以A处 取他们里面最小的0.

一次类推便可以得到memoization

想想为什么初始化第一列和第一行由0递增?答案在代码中:

https://github.com/kcrosswind/leetcode/blob/master/Solution_minDistance.java

 

部分位子摘自:http://wdhdmx.iteye.com/blog/1343856

http://blog.csdn.net/v_JULY_v/article/details/6110269