第一部分:分治法
1.1基本思想
分而治之:将原始问题(难以解决的大问题)分解为若干个规模较小的相同的子问题,在逐个解决各个子问题的基础上,得到原始问题的解。
1.2分类
根据如何由分解出的子问题得出原始问题的解,分治策略可分为两种情形:
1. 原始问题的解只存在于分解出的某一个(或某几个)子问题中,则只需要在这一(或这几个)子问题中求解即可;EXP图书馆找书
2. 原始问题的解需要由各个子问题的解再经过综合处理得到。EXP学校评三好学生
1.3效果
适当运用分治策略往往可以较快地缩小问题求解的范围,从而加快问题求解的速度。
分治策略运用于计算机算法时,往往会出现分解出来的子问题与原始问题类型相同的现象;
而与原始问题相比,各个子问题的尺寸变小了。这刚好符合递归的特性。
因此,计算机算法中的分治策略往往与递归联系在一起。
1.4算法思想的典型应用
MAXMIN问题
二分搜索
合并排序
寻找第K小的元素
大整数的乘法
矩阵相乘
第二部分:减治
2.1 基本思想
减治技术利用了一种关系:一个问题给定实例的解和同样问题较小实例的解之间的关系。(利用了解之间的关系,也就是说可以减少相应的计算,也可以说是一种时空平衡)
一旦建立了这样一种关系,我们既可以递归地,也可以非递归地地来运用减治技术。
2.2分类
减治法有3种主要的变种:
1. 减去一个常量 (decrease by a constant)
2. 减去一个常数因子(decrease by a constant factor)
3. 减去的规模是可变的(variable size decrease)
2.3减去一个常量
在减常量变种中,每次算法迭代总是从实例规模中减去一个规模相同的常量。一般来说,这个常量等于一。
函数f(n) = an可以用一递归定义来计算
f(n) = f (n-1) a 如果n > 1
= a 如果n = 1
虽然时间复杂度和蛮力法一致,但是体现的思想却不一样!
2.4减去常量因子
减常因子技术意味着在算法的每次迭代中,总是从实例的规模中减去一个相同的常数因子。在的多数应用中,这样的常数因子等于二。
计算an的值是规模为n的实例;
规模减半(常数因子等于二)的实例计算就是an/2 的值;
它们之间有着明显的关系: an = (an/2)2。
an = (an/2)2 n是正偶数
= (a(n-1)/2)2 a n是大于1的奇数
= a n = 1
上式递归根据所做的乘法次数来度量效率,该算法属于O (log n);
因为,每次迭代的时候,以不超过两次乘法为代价,问题的规模至少会减小一半。
该算法和基于分治思想的算法有所不同:
分治算法对两个规模为n/2的指数问题实例分别求解:
an = an/2 * an/2 如果n>1
= a 如果n = 1
分治法对应的时间复杂度是:O(n)
也就是说分治法是分解的部分需要进行分开的单独计算(需要计算两遍),而减治法则利用了"一个问题给定实例的解和同样问题较小实例的解之间的关系"从而减少了计算量
2.5减可变规模
在减治法的减可变规模变种中,算法在每次迭代时,规模减小的模式都是不同的。
例如:欧几里德算法
2.6算法思想的典型应用
减去一个常量:
插入排序
快速排序(每一次运行一次划分算法都只是排好了一个元素)
深度优先查找
广度优先查找
拓扑排序
生成排列
生成子集
减去常量因子:
折半查找
假币问题
减可变规模
二叉查找树
第三部分:变治
根据对问题实例的变换方式,变治 思想有3种主要类型:
• 变换为同样问题的一个更简单或者更方便的实例—实例化简(Instance simplification)。
• 变换为同样实例的不同表现—改变表现(Representation Change).
• 变换为另一个问题的实例, 这种问题的算法是已知的—问题化简(Problem reduction).
实例化简
检验数组中元素的惟一性--实例化简_预排序
模式计算--实例化简_预排序
AVL树--二叉排序树
改变表现
2-3树、2-3-4树--二叉排序树
堆和堆排序
霍纳法则--多项式的计算
问题化简
背包问题--线性规划