文章目录
1 算法概述
1.1 什么是算法
- 解决问题的步骤
1.2 为什么要学习算法
- 算法可以衡量程序员的技术功底
- 算法可以体现程序员的学习能力和成长潜力
- 学习算法有助于提高分析解决问题的能力
- 学习算法是做性能优化、成长为架构师的必经之路
1.3 算法的魅力
- 求和1+2+3+4…+100
- 常规方法:遍历每个数求和
- 好的算法:(1+100)* 100/2
- 由此可见 好的算法可以化繁为简,举重若轻
1.4 怎么衡量一个算法的好坏
- 时间复杂度(最重要的)
- 空间复杂度
1.5 常见的算法的时间复杂度—衡量算法的性能
1.6 怎么学好算法
- 刷题 往死里刷
1.7 算法的分类
- 按照应用目的
- 搜索算法
- 排序算法
- 字符串算法
- 图算法
- 最优算法
- 数学算法
- 按照实现思想
- 暴力法
- 增量法
例如: 插入排序
- 分支法
- 什么是分支法:将一个大问题不断分解为一个个可以解决的子问题,所有子问题的解合起来就是大问题的解
- 什么情况下可以用分支法: 产生的子问题形式往往和原问题相同,只是原问题的较小规模的表达。子问题合并可以得到上一层的解,上一次解的合并又可以得到上上一层的解。往复如此得到最终问题的解。
- 贪心算法
- 动态规划
- 回溯法
- 分支限界发
2 算法思想- 分支法
2.1 什么是分支法
- 将一个大问题不断分解为一个个可以解决的子问题,所有子问题的解合起来就是大问题的解
2.2 什么情况下可以用分支法
- 产生的子问题形式往往和原问题相同,只是原问题的较小规模的表达。
- 子问题合并可以得到上一层的解,上一次解的合并又可以得到上上一层的解。往复如此得到最终问题的解。
2.3 基本步骤
- 将原问题分解为若干个规模较小,相互独立 与原问题形式相同的子问题
- 若子问题规模较小而容易被解决则直接解决,否则递归解决各个子问题
- 将各个子问题的解合并为原问题的解
2.4 应用场景
- 二分查找 大整数乘法 归并排序 快排
- 棋盘覆盖问题 循环赛日常表 汉诺塔
3 算法思想- 贪心法
3.1 什么是贪心算法
- 不考虑整体 只考虑眼前,得到局部最优解
3.2 局部最优解和全部最优解的关系
- 局部最优解不一定是全局最优解,要保证最终得到是全局最优解,贪心策略必须具备无后效性
3.3 适用场景
- 哈夫曼编码
- 用贪心算法直接求解全局最优,条件比较苛刻
3.4 实现思路
从问题的某一初始解出发;
while (能朝给定总目标前进一步) {
利用可行的决策,求出可行解的一个解元素 ;
}
由所有解元素组合成问题的一个可行解;
4 算法思想- 动态规划
4.1 什么是动态规划
- 把原问题划分成多个“阶段”,依次来做“决策”,得到当前的局部解
- 每次决策依赖于当前的“状态”,随即引起状态的转移
- 一个决策序列就是在变化的状态中产生出来的
- 这种多阶段决策最优化,解决问题的过程就称为 动态规划
4.2 动态规划的流程
4.3动态规划的流程
- 最优二叉搜索树
- 最长公共子序列
- 背包问题
5 算法思想- 回溯法(通用解题法)
5.1什么是回溯法
- 选优搜索法
- 按照一定的选优条件,不停向前搜索,直到达到目标
- 如果搜索到某一步,发现之前的选择并不优,就退回一步重新选择
6 算法思想- 深度优先搜索(DFS)策略
- 在包含问题所有解的解空间树中,按照深度优先搜索的策略,从根结点出发、深度搜索解空间树
- 回溯法就是对隐式图的深度优先搜索算法
7 算法思想- 深度优先搜索(DFS)策略
- 所谓“分支”,就是采用广度优先的策略,依次搜索当前节点的所有分支
- 抛弃不满足约束条件的相邻节点,其余节点加入“活节点表”
- 然后从表中选择一个节点作为下一个扩展节点,继续搜索
8 算法思想- 限界策略
- 为了加速搜索的进程,一般会在每一个活节点处,计算一个函数值
- 根据这些已计算出的函数值,从当前活节点表中选择一个最有利的节点作为扩展节点,使搜索朝着解空间树上有最优解的分支推进,以便尽快地找出一个最优解
9 一些经典算法
- 二分查找
- 快排 归并
- KMP算法
- 快慢指针法
- 普利姆和克鲁斯卡算法
- 迪克斯特拉算法
- 其他优化算法:模拟退火,蚁群 遗传算法