随笔分类 - 算法导论
《MIT 6.006 Introduction to Algorithms》课程笔记。
摘要:这节课主要讲的计算复杂度,一般有三种表达不同程度的计算复杂度,如下图所示: P:多项式时间; EXP:指数时间; R:有限时间内。 上图还给了一些问题的计算复杂度的对应结果,关于一些细节例如NP, NP-hard等,下面会深入讲到。 在现实应用中,大多数决策问题是不可计算的。 我们先来看下NP是什么
阅读全文
摘要:之前我们讲到动态规划五步中有个Guessing猜,一般情况下猜有两种情况: 在猜和递归上:猜的是用于解决更大问题的子问题; 在子问题定义上:如果要猜更多,就要增加更多子问题。 下面我们来看如果像背包问题那样子问题比较多,该怎么去解决? 一、Piano / Guitar Fingering 给定n个按
阅读全文
摘要:这节课主要针对字符串/序列上的问题,了解如果使用动态规划进行求解。上节课我们也讲过使用前缀和后缀的概念,他们如下所示: 接下来,我们通过三个问题来深入了解下动态规划使用前缀、后缀和子串怎么去解决括号问题,编辑距离,背包问题。 一、括号问题 Parenthesization 在进行一些列矩阵乘法时,我
阅读全文
摘要:这节课通过讲解动态规划在文本对齐(Text Justification)和黑杰克(Blackjack)上的求解过程,来帮助我们理解动态规划的通用求解的五个步骤: 动态规划求解的五个“简单”步骤: 定义子问题; 猜部分解决方法; 关联子问题的解决方法; 递归&记录 或者 构建自下向上的动态规划表; 解
阅读全文
摘要:这节课讲动态规划的内容,动态规划是一种通用且有效的算法设计思路,它的主要成分是“子问题”+"重用"。它可以用于斐波那契和最短路径等问题的求解上。 一、斐波那契 首先,我们来看下斐波那契问题是什么?传统做法和动态规划法有什么区别? 从上图就能很明显地看出动态规划采用了memorization的思路,将
阅读全文
摘要:在之前的课我们讲过了Dijkstra算法,先回顾下,如下图: 那么如果加速DIjkstra算法寻找最短路径呢?这节课上讲师讲了两种方法:双向搜索(Bi-Directional Search)和目标方向搜索(Goal-Directed Search)。 一、 双向搜索(Bi-Directional S
阅读全文
摘要:如果出现下图所示的负循环,会有相关点的当前最短路径为undefined(即无法定义)。 之前我们也看过通用的最短路径算法思路,如下图所示: 这种通用算法会有两个问题: 时间复杂度呈指数性。 如果出现负循环,最短路径的计算会无法中止。 第一个问题能被Dijkstra算法解决,但它不能解决负循环带来的问
阅读全文
摘要:先回顾下上节课的内容: 下面来看一个定理:对于所有的点来说,放松操作总是满足 d[v] ≥ δ(s, v)。即点s到点v的最短路径总是小于或等于当前点d的路径权重。证明如下: 在正是进入复杂的图前,先看个简单的有向非循环图DAG(Directed Acyclic Graphs),内无负循环。下图是讲
阅读全文
摘要:首先简单介绍下最大路径问题:给定一个加权图,找到两点之间最短加权路径,本质上就是求两点之间哪条路径的权重和最小。有两种算法去做:Dijkatra和Bellman-Ford,后面几节课会专门讲这两个算法。 下面我们先来看看加权图中是怎么定义最短路径和一些数据结构的概念的: 其实主要就下面两个概念需要注
阅读全文
摘要:一、深度优先搜索 它的定义是:递归探索图,必要时要回溯,同时避免重复。 关于深度优先搜索的伪代码如下: 左边DFS-Visit(V, Adj.s)是只实现visit所有连接某个特定点(例如s)的其他点。右边是实现整张图的visit,即DFS(v, Adj)。DFS-Visit是DFS的重要组成模块。
阅读全文
摘要:一、图 在正式进入广度优先搜索的学习前,先了解下图: 图分为有向图和无向图,由点vertices和边edges构成。图有很多应用,例如:网页爬取,社交网络,网络传播,垃圾回收,模型检查,数学推断检查和解谜等。 下面拿Pocket Cube魔方(2x2x2立方体魔方)来举个例子: 对于解魔方来说,可以
阅读全文
摘要:首先让我们回顾下上节课讲的,用牛顿法计算√2的内容: 简单来说,牛顿法从x0=1不断向后计算逼近√2的值,而刚开始计算的精度是1,随着牛顿法的逼近(共log2d个循环),就能使得√2逼近值的精度达到d。在逼近过程中,精度的变化为Quadratic convergence二次收敛趋势(即1,2,4,6
阅读全文
摘要:很多人不喜欢√2的表达,他们认为它不是一个数。 一、卡塔兰数 Catalan numbers 在数方面上,有个著名的数叫卡塔兰数 Catalan numbers,它是组合数学中一个常在各种计数问题中出现的数列。其中它能解决一个叫求括号化方案数量的问题。如图下: 在卡塔兰数下,设P为平衡的父字符串集。
阅读全文
摘要:前几节课讲散列表的时候,我们需要用Chaining,链接法需要用到指针pointer,但有一种方法可以不要Chaining和指针,还能在发生冲突时,为产生冲突的关键字寻找下一个“空”的Hash地址。这种方法叫:开放定址法(Open Addressing)如下图所示: 在开放定址法中,用到探测法(Pr
阅读全文
摘要:在整理课程笔记前,先普及下课上没细讲的东西,就是下图,如果有个操作g(x),它最糟糕的时间复杂度为Ο(c2 * n),它最好时间复杂度是Ω(c1 * n),那么θ则为Θ(n)。简单来说:如果O和Ω可以用同一个多项式表示,这里为c * n,那么这个多项式n就是我们所要求的渐进紧的界θ了: 上节课我们讲
阅读全文
摘要:一、字典 在之前课里,如果我们要实现插入,删除和查找,使用树结构,最好的时间复杂度是AVL下的Ο(log2n),使用线性结构,最好的复杂度为基数排序Ο(n)。但如果使用字典数据类型去做,时间复杂度可为Ο(1)。下面是对字典和Python中字典的相关内容: 字典本质上就是一个直接可接入的表,每个键内可
阅读全文
摘要:在前6节课讲的排序方法(冒泡排序,归并排序,选择排序,插入排序,快速排序,堆排序,二分搜索树排序和AVL排序)都是属于对比模型(Comparison Model)。对比模型的特点如下: 所有输入items是黑箱(ADTs, Abstract Data Types); 允许的操作只有对比(<,≤,>,
阅读全文
摘要:之前第5节课留了个疑问,是关于“时间t被安排进R”的时间复杂度能不能为Ο(log2n)?”和BST时间复杂度Ο(h)的关系。第6节对此继续了深入的探讨。首先我们知道BST的h是指树的高,即从根到叶子结点最长路径的长度。但由于树结构不同平衡情况,高h的结果也不一样,如下图所示: 一、结点的高 由此可以
阅读全文
摘要:第5节课主要讲述了二分搜索树概念和BST排序。讲师提出一个关于“跑道预订系统”的问题,假设飞机场只有一个跑道,飞机需要为未来降落时间t进行预订,如果时间集合R中,在t时间前后k分钟内没有其他飞机着陆计划,时间t可以被安排进R中。那么请问“时间t被安排进R”的时间复杂度能不能为Ο(log2n)(假设R
阅读全文
摘要:第4节课仍然是讲排序,但介绍的是一种很高效的堆排序。 在编程过程中,有时候会需要进行extrat_max的操作,即从一个数列里挨个抽取最大值并将其它从原数列中移除。而排序问题也可以看作是一个extract_max的行为,不断的从原始数列中抽取最大值并进行移除,这样挨个抽取的最大值输出后能得到一个降序
阅读全文