一、算法思想
(一)递归(recursion)
直接或间接地调用自身的算法称为递归算法。用函数自身给出定义的函数称为递归函数。每个递归函数都要有非递归定义的初始值。
关键要素:边界条件、递归方程
典型案例:斐波那契、汉诺塔
(二)分治法(divide and conquer method)
将一个规模为n的问题分解为k个规模较小的子问题,这些子问题相互独立且与原问题相同。递归的解这些子问题,然后将各个子问题的解合并得到原问题的解。
典型案例:二分法、归并排序、快速排序、汉诺塔
(三)动态规划法(dynamic programing method)
和分治法类似,都是将待求问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。而动态规划的子问题往往是重叠的,即相互不独立,所以可以用一个表来记录所有子问题的解,以免之后大量重复计算。
关键要素:最优子结构、重叠子问题、状态转移方程
典型案例:凑零钱、背包问题
(四)贪心法(greedy method)
贪心算法并不从整体的最优解考虑,而是做出当前的局部最优的选择。两个要素是最优子结构和贪心选择性质,贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择(即贪心选择)来达到。
关键要素:最优子结构、贪心选择性质
典型案例:无重叠区间、活动安排问题
(五)回溯法(back track method)
回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法。
两种典型的解空间树:子集树、排列树
典型案例:N皇后问题、图的m着色问题
(六)分支限界法(branch and bound method)
分支限界法按广度优先策略遍历问题的解空间,在遍历过程种,对已经处理的每一个结点根据限界函数估算目标函数的可能值,从中选取使目标函数取得极值(极大或极小)的结点优先进行广度优先搜索,从而不断调整搜索方向,尽快找到问题的解。因为界限函数常常是基于问题的目标函数而确定的,所以,分支限界法适用于求解最优化问题。
常见两种分支限界法:
(1)队列式(FIFO)分支限界法:按照队列先进先出(FIFO)原则选取下一个节点为扩展节点。
(2)优先队列式分支限界法:按照优先队列中规定的优先级选取优先级最高的节点成为当前扩展节点。
典型案例:0/1背包问题、单源最短路径问题、最优装载问题。
(七)十大经典排序算法
菜鸟教程:https://www.runoob.com/w3cnote/ten-sorting-algorithm.html
(八)七大查找算法
https://www.cnblogs.com/maybe2030/p/4715035.html#_labelTop【C++】
二、算法差异
(一)分治法和动态规划法的区别
共同点:都是将问题分解为子问题,求解子问题,记录子问题的解,然后合并子问题的解得到原问题的解。
不同点:动态规划解决的问题一定是最优化问题,并且拥有重叠子问题;分治法解决的问题不一定是最优化问题,分解出的子问题是不重叠的,是相互独立的。
(二)动态规划法和贪心法的区别
共同点:贪心算法和动态规划算法都是解决最优化问题,并要求问题具有最优子结构性质。
不同点:
动态规划:每一步作一个选择——依赖于子问题的解。
贪心方法:每一步作一个选择——不依赖于子问题的解。
动态规划方法的条件:最优子结构性质;重叠子问题性质。
可用贪心方法的条件:最优子结构性质;贪心选择性质。
动态规划:自底向上求解(动态规划方法是自底向上计算各个子问题的最优解,即先计算子问题的最优解,然后再利用子问题的最优解构造大问题的最优解,因此需要最优子结构)
贪心方法: 自顶向下求解。
(三)回溯法和分支限界法的区别
共同点:一种在问题的解空间树上搜索问题解的算法。
不同点:
求解目标不同,回溯法的目标是找出解空间树满足约束条件的所有解,而分支限界法的求解目标是尽快地找出满足约束条件的一个解;
搜索方法不同,回溯法采用深度优先方法搜索解空间,而分支限界法一般采用广度优先或以最小消耗优先的方式搜索解空间树;
对扩展结点的扩展方式不同,回溯法中,如果当前的扩展结点不能够再向纵深方向移动,则当前扩展结点就成为死结点,此时应回溯到最近一个活结点处,并使此活结点成为扩展结点。分支限界法中,每一次活结点只有一次机会成为扩展结点。活结点一旦成为扩展结点,就一次性产生其所有儿子结点;
存储空间的要求不同,分支限界法的存储空间比回溯法大得多,当内存容量有限时,回溯法成功的可能性更大。