复习参考:
《算法设计与分析基础》潘彦译
【北大公开课】 算法设计与分析
【算法设计与分析】期末考试知识总结(知识超浓缩版)
《算法分析与设计》复习笔记
【期末知识点整理】算法设计与分析
算法设计与分析——算法复杂性分析
算法是一系列解决问题的明确指令。换言之,对于符合一定规范的输入,能够在有效时间内获得要求的输出。
算法:具有输入、输出、确定性、有限性。
程序(算法+数据结构=程序):具有输入、输出、确定性(注意:程序可以不满足有限性,如操作系统是在无限循环中执行的程序)。
衡量算法好坏的方法:正确性(有限时间正确结果)、简明性、效率(时间、空间)、最优性
算法的基本特征
背包问题
渐进意义下的符号:
Ο,表示渐进上界(tightness unknown),小于等于的意思,近似复杂度。
Ω,表示渐进下界(tightness unknown),大于等于的意思,近似复杂度。
Θ,表示确界,既是上界也是下界(tight),就是相等,准确的复杂度。
常见的时间复杂度大小关系:O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3) < O(2n) < O(n!) < O(nn)
分析非递归算法效率的通用方案
分析递归算法时间效率的通用方案
对于递归式T(n) = aT(n/b) + f(n),比较根节点代价之和f(n)和叶子节点代价之和的大小
也就是在比较合并成本和叶子成本,究竟谁更大。粗略的理解如下:
① f(n)多项式意义大于 ,不止渐进大于且相差n^ε,所以总体代价以f(n)为主;(这里忽略了对正则条件的理解,感觉不影响使用,想了解深层原理可以看一下课本)
② f(n)与 等阶,最后的结果要再乘以logn
③ f(n)多项式意义小于,不止渐进小于且相差n^ε,所以总体代价为
这三种情况画在线段上如下图所示,所以中间哪些无法覆盖的部分就是这个定理无法涵盖的情况。具体的讲解还是可以看看那个北航老师的视频。
注意:要使用第三种情况,需要满足条件验证,其中c<1
【概述】蛮力法是一种简单、暴力、直接解决问题的方法,通常直接基于问题的描述和所涉及的概念定义,依赖计算机的计算速度直接求解。
【步骤】搜索所有的解空间、搜索所有的路径、直接计算、模拟和仿真。
【理解】有的暴力枚举即可,有的直接模拟即可。
时间复杂度为O(nm),其中n是主字符串的长度,m是模式字符串的长度
空复O(1)
暴力法 时复Θ(n2)
最近对问题的一个最重要的应用是统计学中的聚类分析。(填空)
找出一条n个给定城市间的最短路径,其中要求回到出发的城市&每个城市都只访问一次。则该问题可以理解为求一个图的最短哈密顿回路问题。
哈密顿图(哈密尔顿图)(英语:Hamiltonian graph,或Traceable graph)是一个无向图,由天文学家哈密顿提出,由指定的起点前往指定的终点,途中经过所有其他节点且只经过一次。在图论中是指含有哈密顿回路的图,闭合的哈密顿路径称作哈密顿回路(Hamiltonian cycle),含有图中所有顶点的路径称作哈密顿路径(Hamiltonian path)
时复 O(2n)
有n个任务分配给n个人执行,一个任务对应一个人。给出对于每个任务,这n个人完成分别的成本。求总成本最小的分配方案。
邻接矩阵O(n2)
邻接表O(n+e)
空间复杂度相同,都是O(n)
使问题变成与原问题相同的但是规模更小的子问题,解决这个子问题,延伸子问题的解决方法,从而得到原问题的解决方案
减一
删去入度为0的点
在n枚外观相同的硬币中,有一枚是假币。在一架天平上,可以比较任意两组硬币,即通过观察天平是向右倾还是左倾或中间,课判断哪组更重。假设假币较轻。
进一步优化:增加堆数
折半的优化
where:有序表
【概述】对于一个规模为n的问题,若该问题可以容易的解决(比如n的规模较小)则直接解决,否则将其分解为k个规模较小的子问题(即具有最优子结构性质),这些子问题互相独立且与原问题形式相同,递归地解决这些子问题,然后将各子问题的解合并得到原问题的解。
优点:稳定性
缺点:需要线性的额外空间
平均性能O(nlogn)
四次变三次,减少乘法次数
=》通过代数变换,减少a(规约后的子问题个数)
1、问题描述
求空间内,最近的两个点(最简单的就是一维问题,然后可以上升为二维的)
2、一维的最近点对的解题思路
同理,先分析是否满足分治法的适用条件:可以把空间分成两部分,求每个小空间的最近距离,但是在合并的时候,交界处比较难处理,但是也算是满足条件
合并策略:如果说两个点集的交界处有更近的点,那找到这俩个点,需要扫描的范围其实不会超过,两边的最近距离d的二倍,画个图如下所示,这2d的范围中,最多只可能会有4个点,如果说p1和p2之间还有其他的的点,那就会构成比d更近的距离了
所以,合并的时候,我们需要在从分割点 出发 分别往左右扫描扫描到d的距离,看看是否会出现更近的情况就可以啦
3、二维最近点对问题的解题思路
有了一维的基础,再考虑二维的问题就好理解多了,直接来分治法求解过程:
(1)预处理:将点集P中的点,按照X Y坐标从小到大顺序排列
(2)分解:计算x坐标中位数m,选择一条垂线L:x=m,将点集P分成左右两部分PL和PR,分解到最后的递归出口,剩1~3个点时,就可以直接计算了
(3)解决:递归调用该算法,分别找PL和PR中的最近点对及距离,距离分别记为δL, δR,置δ = min(δL, δR)
(4)合并:考察带状区域中的点
① 找出以L为中心线,宽度为2𝛿的带状区域
② 获得带状区域中排序后的点集Y’
③ 对Y’中的每个点,检查其后面的7个点,计算距离并更新最近点对的距离
为啥是7个点呢,看以下分析:
其实跟一维一个道理,再这个带状区域中,最多只可能存在8个点,如下图,因为如果再想多一个点,就会在L的一边存在比δ更进的距离,所以,只需要分析一个点往后的7个点就足够了
4、时间复杂度分析
递归式为:T(n) = 2T(n/2)+f(n)
f(n) = O(n)
得出最后时间复杂度:==> T(n) = O(nlgn)
解凸包问题的分治算法也称为快包(因为它的操作和快排操作类似)
总体时间复杂度O(nlogn),最差效率Θ(n2)
若列表是有序的,许多关于列表的问题更容易求解
(联想 线代中的初等变换来实现消元)
A[i,i]可能会非常小
=>A[j,i]/A[i,i]会很大
=>A[j,k]的新值会因为舍入误差而歪曲
为了避免该问题,每次都去找第i列系数的绝对值最大的行,再把它作为第i次迭代的基点。
这种修改,称为部分选主元法。它保证比例因子的绝对值不会大于1
在AVL树中,任一节点对应的两棵子树的最大高度差为1
插入 时复(logn)
跟avl树的插入方式一样,只不过每一个结点可以容纳1~2个结点,当结点数量到达三个时,就会“分裂”成一个小avl树
堆是一棵完全二叉树&每个节点的键都要大于或等于其子女的键(以大根堆为例)
堆排序时复Θ(nlogn),空复O(1)
解决多项式问题的一种重要算法是快速傅里叶变换,基本思想是用多项式在某些特定点上的值来表示该多项式。
时复O(n)
用霍纳法则计算an,时复O(n)
用从左至右二进制幂算法计算a13,n=13=11012(期末可能考该类题)
作为一种算法设计技术,空间换时间 要比 时间换空间 更为普遍
字符匹配蛮力算法最差性能是O(nm),其中m是模式串的长度,n是字符串长度。
最差效率O(nm)
平均情况下时复O(n)
时复O(n)
B树进行查找、插入和删除的时间效率都是O(logn)
【概述】动态规划是一种解决多阶段决策问题的优化方法,把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解。能用动态规划法的问题一般具有3个性质:最优子结构,无后效性,有重叠子问题。
【步骤】分析最优解的性质,递归的定义最优解;以自底向上或自顶向下的记忆化方式计算出最优值;根据计算最优值时得到的信息,构造问题的最优解。
【理解】自底向上的构建过程。
最优的(即平均比较次数最少的) 二分检索树
复杂性估计:
时间复杂性:T(n)=O(n3)
空间复杂性: S(n)=O(n2)
Warshall算法——计算有向图的传递闭包
Floyd算法————计算全部的最短路径
结束时间早的优先
排序使得f1≤f2≤…≤fn,从前向后挑选(fi是活动i的结束时间)
时复O(nlogn)
一个给定网络的可行流是实数值xij对边(i,j)的分配,使得网络满足流量守恒约束和容量约束
找最小割:正向饱和的点和汇点一同做补集
n为顶点数,m为颜色种类数