最初看的学习视频来自 : 爱学习的饲养员。后来又看到了更好的视频,来自:大雪菜。(从他讲DP入的坑。)
爱学习的饲养员的个人空间_哔哩哔哩_bilibilihttps://space.bilibili.com/31337561/channel/seriesdetail?sid=389852b站-大雪菜-闫学灿-北大-ACWing
https://space.bilibili.com/7836741##目前,闫总团队讲的最专业。
一、双指针
用多个指针解决问题。也有三指针、四指针。
普通双指针:两个指针往同一个方向移动,(有时候是不同方向。这里特指复杂度是O(n^2)的暴力法);
对撞双指针:两个指针面对面移动;
快慢双指针:慢指针+快指针;
----------
例题:a=[1,4,5,7,9],两个数相加=12。
普通2指针:两个for循环
对撞双指针:先排序,左小右大。i指向头,j指向尾。求和sum,若sum大于12,那么最右边的j左移,(sum缩小了);若sum小于12,那么最左边的i右移,(sum扩大了);直到sum等于12。
--------
快慢双指针,判断链表是否是环形的。
二、二分查找
针对有序数组。(左小右大)。查target值是否存在于数组里,从子数组的中间值,如果该值小于target,则取右子数组,下次在右子数组里找target;如果该值大于target,则取左子数组,下次在左子数组里找target。
O(log2(N)).
----------------
三、滑动窗口
目的:减少while循环
例:a=[1,4,2,3,4,5,6],数组连续3个数,取最大的和。
直接算也能做。
观察:当计算了1+4+2以后,再计算4+2+3,那么4+2就重复计算了。
优化:当计算过一组数的sum以后,要计算下一组的sum,只需要减去 [出去的数],加上
[进来的数],就达到减少重复计算的目的了。将固定长度的连续数组比作滑动窗口,窗口越长,减少重复运算的效果就越明显。
解决数组中定长问题。
四、递归
递归的定义:函数直接或间接地调用自己。
递归 | |
回溯 | |
深度优先搜索 DFS | |
分治法 Divide & Conquer |
递归的4要素
接受的参数 | ||
返回值 | ||
终止条件 | ||
递归拆解:如何递归到下一层 |
//递归在使用的过程中,会保存很多中间变量,占用了额外的资源。程序员写起来容易,但是更推荐迭代。
从实现角度讲,迭代是在局部内存进行重复计算,递归需要展开栈空间进行每一步的函数现场存储和结果存储。迭代没有这个展开的开销。(知乎:Larry Sean)
五、分治法
大问题分成小问题,然后小问题求解,最后合并。
用到了递归,自己调用自己。
-----以归并排序为例:a=[7,8,4,1,6,5,2,3],排序
把数组a对半分; [7,8,4,1], [6,5,2,3]
[7,8],[4,1],[6,5],[2,3]
分成两两一组,进行两两排序。
[7,8], [1,4], [5,6], [2,3]
相邻合并 [1,4,7,8] ,[2,3,5,6]
[1,2,3,4,5,6,7,8]
有更清楚的讲解
图解排序算法(四)之归并排序 - dreamcatcher-cx - 博客园 (cnblogs.com)https://www.cnblogs.com/chengxiao/p/6194356.html
六、回溯法
类似枚举,一层一层向下递归,尝试搜索答案。把所有可能的结果枚举出来,然后排除不符合的结果,保留符合的结果。
例子:返回数组a=[1,2,3]的所有子集。
找到所有的可能,分为子集长度为0,1,2,3的情况。
分情况讨论:先走到长度为0的情况,只有[],保存结果,回溯到分情况讨论;
再走到长度为1的情况,[1],[2],[3],保存结果,回溯到分情况讨论;
再走到长度为2的情况,[1,2],[1,3],[2,3],保存结果,回溯到分情况讨论;
再走到长度为3的情况,[1,2,3],保存结果,回溯到分情况讨论;
没有其他可能的情况了,返回所有结果。
----------------------------
七、深度优先搜索 DFS
用到了递归的思想。
分治法;
回溯法。
DFS:从root节点开始,尽可能深的搜索每一个分支。(把一个分支的结果搜索完,再去看下一个分支。)
应用:二叉树搜索、图搜索。
八、广度优先搜搜 BFS
九、并查集 Union Find
union:合并两个元素为同一个根节点
find:找到某个元素的根节点
十、贪心算法
核心:每一步做出的都是当前看起来最好的选择,局部最优选择。
使用贪心算法,会把大问题分成多段级联的小问题,取每一级的最优解,最后联合起来这些答案。
视具体情况而定,局部最优通常不是全局最优。
例:最少的硬币,凑够11元,硬币面值有v=[1,2,5].
显然,硬币最少,则推荐多用大面值的硬币。
选用硬币面值 | 剩余金额 |
5 | 11-5=6 |
5 | 6-5=1 |
1 | 1-1=0 |
十一、记忆话搜索-算法记忆化-备忘录
目的:减少重复计算。---把计算过的式子和结果记下来,下次遇到直接用,不需要再计算。
例如斐波那契数列的计算。
F(n)=F(n-1)+F(n-2),...F(0)=0,F(1)=1,
拆分计算的时候,不需要重复算了,直接背住。
十二、动态规划
例如:机器人从左上角移动到右下角,智能右移、下移,有多少路径?
start | |||
end |
答:到end的路径数=m+n。
start | |||
m | |||
n | end |
可以推导出:
位置[r][c]的路径数
状态转移方程式 ----> [r][c]=[r-1][c]+[r][c-1],
初始状态 ----> [0][0]=1,[r][0]=1,[0][c]=1.
------斐波那契也能用动态规划做,更容易理解。
动态规划可以做哪些类型的题:1计数:有多少种方式、方法
机器人从左上角到右下角的路径数
2求最值:最大/最小值
机器人从左到右路径的最大数字和(有正有负,不定长度)
3求存在性:是否存在某个可能
是否存在机器人从左到右的一条什么路径。
一维、二维动态规划。
补充:闫氏分析法.闫氏DP分析法,从此再也不怕DP问题!_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1X741127ZM?spm_id_from=333.999.0.0