第1章:算法概述
算法:具有输入、输出、确定性、有限性。
程序(算法+数据结构=程序):具有输入、输出、确定性(注意:程序可以不满足有限性,如操作系统是在无限循环中执行的程序)。
衡量算法好坏的方法:正确性(有限时间正确结果)、简明性、效率(时间、空间)、最优性
渐进意义下的符号:
O:表示算法的渐近上界,如果算法的时间复杂度为O(g(n)),使得对于任何输入规模n,算法的运行时间都不会超过c * g(n),即算法的时间复杂度不会超过g(n)的某个常数倍,此谓上界。
Ω:表示算法的渐近下界,如果算法的时间复杂度为Ω(g(n)),使得对于任何输入规模n,算法的运行时间都不会低于c * g(n),即算法的时间复杂度不会低于g(n)的某个常数倍,此谓下界。
Θ:表示算法的渐近紧确界,如果算法的时间复杂度为Θ(g(n)),使得对于任何输入规模n,算法的运行时间都被夹在c1 * g(n)和c2 * g(n)之间,即算法的时间复杂度大约是g(n)的某个常数倍,此谓同阶。
第2章:递归与分治
分治法:将规模为n的问题分解为k个规模较小的子问题,子问题间互相独立且与原问题相同。通过递归求解子问题,最后将解合并,可实现对原问题的求解。
(个人总结:分治法的核心思想是:分解和递归。即将大问题分解为子问题,因为子问题性质与原问题相同,因此可以使用相同的递归式进行求解。
注意子问题间的求解必须是独立的,否则会做很多不必要的重复工作,如果子问题间不完全独立的话选择动态规划会比较好。)
分治法求解过程:分解 -> 递归求解 -> 合并。
分治算法典型问题:二分搜索、合并排序、快速排序、大数乘法、矩阵乘法、棋盘覆盖、最近点对问题、线性时间选择、循环赛日程。
排序方法 | 最好时间 | 平均时间 | 最坏时间 | 辅助空间 |
插入排序 | ||||
堆排序 | ||||
冒泡排序 | ||||
快速排序 | ||||
归并排序 |
分治答题策略:
第1步:简单描述所设计的算法,要重点说明是如何将问题划分为子问题(分解策略)
第2步:说明如何进行递归,给出递归方程
第3步:合并过程如果有的话就一句话带过即可
第4步:注意要在最后写上时间复杂度和空间复杂度。
第3章:动态规划
动态规划:将规模为n的问题分解为k个规模较小的子问题,子问题间彼此关联且与原问题相同。通过将子问题的解记录下来,以避免重复计算。动态规划常用于解决具有重叠子问题和最优子结构特性的问题,通常使用表格法或记忆化搜索来实现,最终得到原问题的最优解。
重叠子问题:在递归执行的过程中,同一个子问题会被多次遇到和解决,通过存储已解决子问题的答案,动态规划可以避免对相同子问题的重复计算。
最优子结构:一个问题的最优解包含其子问题的最优解。
(个人总结:动态规划与贪心不同的一点在于:动态规划的子问题间不是完全独立的,换句话说子问题间具有关联或者说是依赖的关系,因此可以用表来记录已解决的子问题答案,后续操作用到时只需要查表即可,不用再重新计算,可以节约开销)
动态规划算法典型问题:最长公共子序列、最大子段和问题、凸多边形最优剖分、多边形游戏、图象压缩、电路布线、流水作业调度、0-1背包问题。
动态规划答题策略:
第1步:简单描述所设计的算法,要重点分析最优解结构(满足最优子结构),简单说明满足重叠子问题性质。
第2步:建立递归关系,给出递归方程。
第3步:计算最优值,即简单描述求解过程,给出时间复杂度,最好给出空间复杂度(表的复杂度)。
第4步:构造最优解
第4章:贪心算法
贪心选择性质:所求问题的整体最优解可以通过一系列局部最优的选择来达到。
证明满足贪心选择性质:证明每一步所做出的贪心选择最终将获得问题的整体最优解。(首先考察问题的一个整体最优解,并证明可修改这个最优解,使其以贪心选择开始。在做出贪心选择后,原问题简化为规模更小的类似子问题。用数学归纳法证明,通过每一步做贪心选择,最终可得到问题的全局最优解。)
最优子结构性质:一个问题的最优解包含其子问题的最优解。
贪心算法典型问题:装船问题、哈夫曼编码问题、单源最短路径问题、最小生成树问题、多机调度问题。
贪心答题策略:
第1步:先描述所设计的算法。
第2步:证明算法的正确性,包括贪心选择性质和最优子结构性质。
第3步:给出时间复杂度。
(如有谬误望请指正,持续更新中)