算法学习日记
文章平均质量分 73
Darkbluelr
这个作者很懒,什么都没留下…
展开
-
算法学习笔记Day8——回溯算法
1.回溯算法是什么?回溯算法就是个多叉树的遍历问题,关键在于在前序和后序时间点做一些操作,本质是一种暴力枚举算法,它和DFS非常相似,区别在于,回溯算法关注点在于树的树枝,DFS关注点在于树的节点。2.回溯算法的技巧站在一棵决策树的节点,需要考虑三个问题:1、路径:也就是已经做出的选择。2、选择列表:也就是你当前可以做的选择。3、结束条件:也就是到达决策树底层,无法再做选择的条件。3. 回溯算法的框架(规律)def backtrack(路径,选择列表){if(满足结束条件){原创 2024-04-25 23:02:45 · 793 阅读 · 0 评论 -
算法学习笔记Day9——动态规划基础篇
第一个斐波那契数列的问题,解释了如何通过「备忘录」或者「dp table」的方法来优化递归树,并且明确了这两种方法本质上是一样的,只是自顶向下和自底向上的不同而已。第二个凑零钱的问题,展示了如何流程化确定「状态转移方程」,只要通过状态转移方程写出暴力递归解,剩下的也就是优化递归树,消除重叠子问题而已。计算机解决问题其实没有任何特殊的技巧,它唯一的解决办法就是穷举,穷举所有可能性。算法设计无非就是先思考“如何穷举”,然后再追求“如何聪明地穷举”。递归是自顶向下,迭代是自底向上。原创 2024-04-24 20:54:48 · 624 阅读 · 1 评论 -
算法学习笔记Day7——二叉树全解
遍历:遍历一遍二叉树得到答案,遍历方式:用一个 函数配合外部变量来实现(回溯算法)traverse也是递归遍历,特点是在递归过程中更新外部变量。递归:定义一个递归函数,通过子问题的答案推导出原问题的答案,递归方式:写出这个递归函数的定义,并利用这个函数的返回值,分解问题(动态规划)i)前序位置的代码在刚刚进入一个二叉树节点的时候执行;ii)中序位置的代码在一个二叉树节点左子树都遍历完,即将开始遍历右子树的时候执行。(很多多叉树没有中序位置,因为一个节点没有唯一的中序遍历位置。)iii)后序位置的代码在将要原创 2024-04-17 21:00:33 · 396 阅读 · 0 评论 -
算法学习笔记——专题拓展4:DFS 算法解决岛屿题目
i)淹没岛屿的作用是,不需要维护visited数组ii)框架:在主函数里,遍历每个块,每当遇到一个大陆,就用dfs去淹没它;dfs里,如果越界或者已经访问过这个块,直接返回,否则,递归访问它的相邻块。维护一个全局变量,dfs的函数里面对它做出更新,然后在主函数返回。原创 2024-04-17 20:58:12 · 440 阅读 · 0 评论 -
算法学习笔记Day1 ——数据结构和算法的框架思维
对于任何数据结构,所进行的操作无非就是遍历+访问,具体一点就是增删改查,遍历方式分为线性(for/while)和非线性(递归),数组是典型的线性遍历,链表是二者结合,二叉树就是典型的递归遍历。其中数组特点是物理上连续、结构紧凑,支持随机访问,但是O(N)增删,因为需要平移数组;是数组(顺序存储)和链表(链式存储),不管是哈希表、树、图、堆栈、队列等,其基本实现方法都只有数组和链表两种。的题目,培养框架思维,因为所有递归算法都是树的遍历,这样在后续学习DP和回溯等算法时会势如破竹。原创 2024-04-05 20:53:19 · 250 阅读 · 1 评论 -
算法学习笔记Day2——双指针技巧之单链表
i). 链表的尽头判断是用 List!= nullprt,而不是List->next!ii). 拼接最后的部分不需要用两个while,直接把节点的结构体赋值过去就可以了。iii). C++中所有NULL都用nullptr代替,为了迎合C++的重载特性。(*NULL 在C++ 里表示。原创 2024-04-06 22:37:26 · 1693 阅读 · 1 评论 -
算法学习笔记Day3——双指针技巧之数组
分析:记录遇到0的次数,最后把0一次性输出到数组末尾即可。 主要用来解决子数组/子串问题,比如最大/最小子数组;思路就是维护一个窗口,然后不断滑动来更新结果。因为left和right指针都不会回退,所以每个元素都只会进入窗口一次,出窗口一次,所以复杂度为O(N)。分析:代码:曾经写的C代码:滑动窗口+模式选择(通过判断当前窗口是否包含所有字符来决定左指针还是右指针滑动),预计C++能节省很多代码量这次写的C++代码: 总结:分析:巧妙思路:使用左右指针,right每次遇到一个字母,在日记本里面查找le原创 2024-04-08 00:32:38 · 699 阅读 · 0 评论 -
算法学习笔记Day4——经典数组技巧:前缀和数组
后面两个都是i-1, sums数组记得要resize到n+1,因为前0个是一个都不取。原创 2024-04-08 23:50:10 · 374 阅读 · 0 评论 -
算法笔记Day5——经典数组技巧:差分数组
前缀和实际上就是求积分(离散),差分就是求导,它们之间互为逆运算。前缀和主要适用于原数组不变,频繁查询某个区间的累加和。差分适用于频繁对某区间的元素进行增减(原数组要变),如果是原数组来操作的话,每次区间加减都需要O(N)的时间复杂度,但是差分数组只需要O(1)的时间复杂度,很多次加减操作的话,这个差距就很大了,差分数组回到原数组需要O(N)的时间复杂度,但是只需要一次。原创 2024-04-10 01:39:26 · 270 阅读 · 1 评论 -
算法学习笔记——专题拓展1:一个方法团灭nSum问题
技巧:1. 如何在排序后保持原数组的下标信息?答:创建一个vector<pair<int, int>> 向量,其中包含下标信息,排序的时候会跟着排序,并且排序默认使用pair的第一个变量排序2. 如何通过迭代器得到下标?答: 使用 distance(nums.begin(), iterator)3. 如何找到某个数字在数组中第一次出现的位置?答: 使用 find( nums.begin(), nums.end(), integer ),得到的是迭代器,如果没有找到返回 nums.end()原创 2024-04-10 10:34:14 · 358 阅读 · 1 评论 -
算法学习笔记Day6——二维数组的花式遍历
矩阵的螺旋遍历的通用模板,设置上下左右四个边界,然后用四个for循环去遍历,i的起始就是螺旋的方向,比如left -> right, up -> down,每铺一层,那一层的变量就对应的增减。原创 2024-04-11 23:54:26 · 199 阅读 · 0 评论 -
算法学习笔记——专题拓展2:数组双指针经典习题
i)对迭代器的增减不会改变数组的长度。ii)截取字符串用 s.substr( begin, length);选取区间是[begin, begin + length), 拼接字符串简单的+就可以。iii)string中的erase:按位置删除:s.erase(int ),直接从第int个位置删除,并且截断字符串(后面的不看了)按位置和长度删除多个字符: s.erase(n, len), 从 n开始删除 len个,不截断,保留后面的。原创 2024-04-12 14:44:44 · 421 阅读 · 0 评论 -
算法学习笔记——专题拓展3:二分搜索
i)C++中找到向量的最大元素的迭代器:max_element( vector.begin(), vector.end()), 取最大值还需要加*II)C++中的求数组元素和,accumulate(vector.begin(), vector.end(), 0), 0表示初始值。原创 2024-04-12 21:55:18 · 290 阅读 · 0 评论