当前课程知识点:数据结构(上) >  第一章 绪论(下) >  (xc)动态规划 >  01XC-7: LCS:递归

返回《数据结构(上)》慕课在线视频课程列表

01XC-7: LCS:递归在线视频

01XC-7: LCS:递归

下一节:01XC-8: LCS:理解

返回《数据结构(上)》慕课在线视频列表

01XC-7: LCS:递归课程教案、知识点、字幕

以下我们就参照

Kent Beck所建议的工作流程

暂时把计算效率放在一边

而是首先考虑得到一个

可行的正确的LCS算法

为此我们需要拿起递归

这个强有力的武器

如果把这个问题形式化一下

我们需要考察的是

计算长度为n+1的一个序列A

以及长度为m+1的一个序列B

之间的LCS

那么这无非可以分为三种情况

第0种情况

也是平凡的情况

n或者m等于-1

这个时候 其中之一是空序列

那么我们知道空序列的子序列

只可能是空序列

所以公共子序列

也必然是空序列

所以不妨直接把空序列

也就是长度为零的一个序列返回

这种情况 在我们算法中

应该是扮演着递归基的角色

那么一般的情况呢?

我们说它有两种

首先来看第一种

这两种的区别也就在于

我们要去比较A序列和

B序列的最后那个字符

也就是末字符

如果它们相等

那么这是第一种情况

这时按照这里所说的

我们可以把最后那个字符去掉

大家注意这里是变成了圆括号

表示是开区间

同时把B序列的末字符抹掉

这样得到它们各自长度

减少一个单元的前缀

这对前缀

如果能够递归地求解出LCS的解

那么再并上

最末尾的这个公共的字符

我们说这样就必然构成了

原来那个问题的解

可以用这样的一个图来表示

也就是说 A序列的末字符

与B序列的末字符 都是相同的

在这个时候

可以大胆地做一个裁切

将二者相同的

这个末字符都忽略掉

保存下来

进而递归地求解

它们各自的那个前缀

所构成最长公共子序列

反过来 一旦求到了以后

只要把X缀在其后

就可以得到原来的解

那么 从任务的递归方向来看

我们也可以用这样的一个图来表示

比如说对于这个例子而言

就是这样一种情况

A序列和B序列

分别列在上下方

在这种情况下

它们的末字符相同

对这个例子而言 都是A

这个时候 我们说原问题

当前这个问题的解是多少

完全取决于

它们去掉这个公共字符之后

各自的前缀合在一起

所构成这样的一个递归的问题

这个问题的解

如果能够递归求出来

那么从长度上讲 只要加1

也就是缀上这个公共的字符

就得到了原问题的解

那么这个箭头

表示的是递归的方向

而且这种递归 从策略上讲

其实就是不折不扣的

Decrease and Conquer 减而治之

从图上也可以看出来

相当于把这个问题

切分成了一个平凡的子问题

以及一个规模小于1

但是形式完全一样的问题

当然互补的 还有第二种情况

也就是说 我们经过判断以后发现

当前的序列A和B的末字符并不相等

这个时候呢 从图上看

可以理解为这样

比如说 A的末字符是X

而B的末字符是Y

它们俩并不相等

这个时候说明

末字符这个位置

肯定是不匹配的

那么原问题的解只有两种可能

一种就是 Y这个字符

对整个的公共子序列没有贡献

这个时候 我们不妨把Y切除掉

然后呢 以Y剩下来的那个前缀

和整个的A 去构成一个子任务

继续递归求解

另外呢 也需要

对称的考虑另一种情况

也就是X对整个

公共子序列的匹配没有贡献

这个时候呢 我们也需要

对称的把A的前缀取出来

然后和整个B序列

构成一个新的子任务

递归地求解

这种情况下

整个问题的解

无非这样上、下两种情况

形式化地 我们来描述

可以认为是把A整体的保留下来

把B的末字符抠掉

构成一个子任务 递归求解

或者对称地

把整个B序列保存下来

而把A的末字符抠掉

构成另一个子任务

所以我们可以看到这两个子任务

一旦递归地获得了解

我们最终只要在它们中间

取一个更长的解

就会得到原来问题的解

所以这样一个策略

如果用图来画的话

继续刚才那个例子

我们可以看到末字符当前

一个是C 一个是T 是不等的

这个时候呢

按照刚才的分析

我们应该沿着两个方向

分别地 递归求解

其一 要把B的末字符

也就是T 抹除掉

继续求解

为此 生成的一个递归实例

可以画在上方

另外对称地 我们也可以

把A序列的末字符 抹掉

从而得到另一个子问题

这个递归实例 从构成上讲

只是比原来的A序列

少了这么样一个末字符

从这个图 也可以很清楚地看到

原问题的解 无非是

左边这个子问题

或者上边这个子问题的解

而且确切地讲 应该是

这二者中的最长者

归纳这三种情况

实际上 我们已经得到了一个

完整的递归算法

不是吗?

我们此前给过递归基

然后呢

下面通过一次对末字符的判断

可以进而区分

下面的非平凡的

第一和第二种情况

而且所有的递归都是封闭的

因此我们把这样一段

具体代码实现 这个任务

交给同学们 在课后完成

而我们转而需要分析的是

这个算法的正确性

以及更重要的效率

我们会发现

这个效率并不是很好

数据结构(上)课程列表:

第零章

-选课之前

--写在选课之前

--宣传片

-考核方式

--考核方式

-OJ系统说明

--关于OJ

--1-注册与登录

--2-界面与选课

--3-提交测试

-关于课程教材与讲义

--课程教材与讲义

-关于讨论区

--关于讨论区

-微信平台

--html

-PA晋级申请

--PA晋级

--MOOC --> THU 晋级申请专区

--THU --> CST 晋级申请专区

--编程作业不过瘾?且来清华试比高!

第一章 绪论(上)

-(a)计算

--01-A-1: 计算

--01a-2: 绳索计算机

--01a-3: 尺规计算机

--01a-4: 算法

--01a-5 : 有穷性

--演示

--01a-6 : 好算法

--(a)计算--作业

-(b)计算模型

--01b-1: 性能测度

--01b-2: 问题规模

--01b-3: 最坏情况

--01b-4: 理想模型

--01b-5: 图灵机

--01b-6: 图灵机实例

--01b-7: RAM模型

--01b-8: RAM实例

-(b)计算模型--作业

-(c)大O记号

--01c-1: 主流长远

--01c-2: 大O记号

--01c-3: 高效解

--01c-4 : 有效解

--01c-5 : 难解

--01c-6: 2−Subset

--01c-7: 增长速度

-(c)大O记号--作业

第一章 绪论(下)

-(d)算法分析

--01d-1: 算法分析

--01d-2: 级数

--01d-3: 循环

--01d-4: 实例:非极端元素+起泡排序

--01d-5: 正确性的证明

--01d-6: 封底估算-1

--01d-7: 封底估算-2

-(d)算法分析--作业

-(e)迭代与递归

--01-E-1: 迭代与递归

--01-E-2: 减而治之

--01-E-3: 递归跟踪

--01-E-4: 递推方程

--01-E-5: 数组倒置

--01-E-6: 分而治之

--01-E-7: 二分递归:数组求和

--01E-8 二分递归:Max2

--01E-09: Max2:二分递归

-(e)迭代与递归--作业

-(xc)动态规划

--01XC-1: 动态规划

--01XC-2: Fib():递推方程

--01XC-3: Fib():封底估算

--01XC-4: Fib():递归跟踪

--01XC-5: Fib():迭代

--01XC-6: 最长公共子序列

-- 演示

--01XC-7: LCS:递归

--01XC-8: LCS:理解

--01XC-9: LCS:复杂度

--01XC-A: LCS:动态规划

-(xc)动态规划--作业

-本章测验--作业

第二章 向量(上)

-(a)接口与实现

--02A-1 接口与实现

--02A-2 向量ADT

--02A-3 接口操作实例

--02A-4 构造与析构

--02A-5 复制

-(a)接口与实现--作业

-(b)可扩充向量

--02B-1 可扩充向量

--02B-2 动态空间管理

--02B-3 递增式扩容

--02B-4 加倍式扩容

--02B-5 分摊复杂度

-(b)可扩充向量--作业

-(c)无序向量

--02C-1 概述

--02C-2: 循秩访问

--02C-3 插入

--02C-4 区间删除

--02C-5 单元素删除

--02C-6 查找

--02C-7 唯一化

--02C-8 遍历

-(c)无序向量--作业

-(d1)有序向量:唯一化

--02D1-1 有序性

--02D1-2 唯一化(低效版)

--02D1-3 复杂度(低效版)

--02D1-4 唯一化(高效版)

--02D1-5 实例与分析(高效版)

-(d1)有序向量:唯一化--作业

-(d2)有序向量:二分查找

--02D2-1 概述

--02D2-2 接口

--02D2-3 语义

--02D2-4 原理

--02D2-5 实现

--02D2-6 实例

--02D2-7 查找长度

-(d2)有序向量:二分查找--作业

第二章 向量(下)

-(d3)有序向量:Fibonacci查找

--02D3-1 构思

--02D3-2 实现

--02D3-3 实例

--02D3-4 最优性

-(d3)有序向量:Fibonacci查找--作业

-(d4)有序向量:二分查找(改进)

--02D4-1 构思

--02D4-2 版本B

--02D4-3 语义

--02D4-4 版本C

--02D4-5 正确性

-(d4)有序向量:二分查找(改进)--作业

-(d5)有序向量:插值查找

--02D5-1 原理

--02D5-2 实例

--02D5-3 性能分析

--02D5-4 字宽折半

--02D5-5 综合对比

-第二章 向量(下)--(d5)有序向量:插值查找

-(e)起泡排序

--02 E-1 构思

--02E-2 改进

--02E-3 反例

--02E-4 再改进

--02E-5 综合评价

-(e)起泡排序--作业

-(f)归并排序

--02F-1 归并排序:构思

--02F-2 归并排序:主算法

--02F-3 二路归并:实例

--02F-4 二路归并:实现

--02F-5 二路归并:正确性

--02F-6 归并排序:性能分析

-(f)归并排序--作业

-本章测验--作业

第三章 列表

-(a)接口与实现

--03A-1 从静态到动态

--03A-2 从向量到列表

--03A-3 从秩到位置

--03A-4 实现

-(a)接口与实现--作业

-(b)无序列表

--03B-1 循秩访问

--03B-2 查找

--03B-3 插入与复制

--03B-4 删除与析构

--03B-5 唯一化

-(b)无序列表--作业

-(c)有序列表

--03C-1 唯一化·构思

--03C-2 唯一化·实现

--03C-3 查找

-(c)有序列表--作业

-(d)选择排序

--03D-1 构思

--03D-2 实例

--03D-3 实现

--03D-4 推敲

--03D-5 selectMax()

--03D-6 性能

-(d)选择排序--作业

-(e)插入排序

--03E-1 经验

--03E-2 构思

--03E-3 对比

--03E-4 实例

--03E-5 实现

--03E-6 性能分析

--03E-7 平均性能

--03E-8 逆序对

-(e)插入排序--作业

-(xd)习题辅导:LightHouse

--03X D 习题辅导:LightHouse

-本章测验--作业

第四章 栈与队列

- (a)栈接口与实现

--04A-1 栈

--04A-2 实例

--04A-3 实现

- (a)栈接口与实现--作业

-(c1)栈应用:进制转换

--04C1-1 应用

--04C1-2 算法

--04C1-3 实现

-第四章 栈与队列--(c1)栈应用:进制转换

-(c2)栈应用:括号匹配

--04C2-1 实例

--04C2-2 尝试

--04C2-3 构思

--04C2-4 实现

--04C2-5 反思

--04C2-6 拓展

-(c2)栈应用:括号匹配--作业

-(c3)栈应用:栈混洗

--04C3-1 混洗

--04C3-2 计数

--04C3-3 甄别

--04C3-4 算法

--04C3-5 括号

-第四章 栈与队列--(c3)栈应用:栈混洗

-(c4)栈应用:中缀表达式求值

--04C4-1 把玩

--04C4-2 构思

--04C4-3 实例

--04C4-4 算法框架

--04C4-5 算法细节

--04C4−6A 实例A

--04C4−6B 实例B

--04C4−6C 实例C

--04C4-6D 实例D

-(c4)栈应用:中缀表达式求值--作业

-(c5)栈应用:逆波兰表达式

--04C5-1 简化

--04C5-2 体验

--04C5-3 手工

--04C5-4 算法

-第四章 栈与队列--(c5)栈应用:逆波兰表达式

-(d)队列接口与实现

--04D-1 接口

--04D-2 实例

--04D-3 实现

-第四章 栈与队列--本章测验

第五章 二叉树

-(a)树

--05A-1 动机

--05A-2 应用

--05A-3 有根树

--05A-4 有序树

--05A-5 路径+环路

--05A-6 连通+无环

--05A-7 深度+层次

-(a)树--作业

-(b)树的表示

--05B-1 表示法

--05B-2 父亲

--05B-3 孩子

--05B-4 父亲+孩子

--05B-5 长子+兄弟

-第五章 二叉树--(b)树的表示

-(c)二叉树

--05C-1 二叉树

--05C-2 真二叉树

--05C-3 描述多叉树

-(c)二叉树--作业

-(d)二叉树实现

--05D-1 BinNode类

--05D-2 BinNode接口

--05D-3 BinTree类

--05D-4 高度更新

--05D-5 节点插入

-(d)二叉树实现--作业

-(e1)先序遍历

--05E1-1 转化策略

--05E1-2 遍历规则

--05E1-3 递归实现

--05E1-4 迭代实现(1)

--05E1-5 实例

--05E1-6 新思路

--05E1-7 新构思

--05E1-8 迭代实现(2)

--05E1-9 实例

-(e1)先序遍历--作业

-(e2)中序遍历

--05E2-1 递归

--05E2-2 观察

--05E2-3 思路

--05E2-4 构思

--05E2-5 实现

--05E2-6 实例

--05E2-7 分摊分析

-第五章 二叉树--(e2)中序遍历

-(e4)层次遍历

--05E4-1 次序

--05E4-2 实现

--05E4-3 实例

-第五章 二叉树--(e4)层次遍历

-(e5)重构

--05E5-1 遍历序列

--05E5-2 (先序|后序)+中序

--05E5-3 (先序+后序)x真

-(e5)重构--作业

-本章测验--作业

第六章 图

-(a)概述

--06A-1 邻接+关联

--06A-2 无向+有向

--06A-3 路径+环路

-(a)概述--作业

-(b1)邻接矩阵

--06B1-1 接口

--06B1-2 邻接矩阵+关联矩阵

--06B1-3 实例

--06B1-4 顶点和边

--06B1-5 邻接矩阵

--06B1-6 顶点静态操作

--06B1-7 边操作

--06B1-8 顶点动态操作

--06B1-9 综合评价

-(b1)邻接矩阵--作业

-(c)广度优先搜索

--06C-1 化繁为简

--06C-2 策略

--06C-3 实现

--06C-4 可能情况

--06C-5 实例

--06C-6 多连通

--06C-7 复杂度

--06C-8 最短路径

-(c)广度优先搜索--作业

-(d)深度优先搜索

--06D-1 算法

--06D-2 框架

--06D-3 细节

--06D-4 无向图

--06D-5 有向图

--06D-6 多可达域

--06D-7 嵌套引理

-(d)深度优先搜索--作业

-第六章 图--本章测验

01XC-7: LCS:递归笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。