算法学习笔记
文章平均质量分 73
Insomnia_X
这个作者很懒,什么都没留下…
展开
-
算法学习笔记——动态规划:高楼扔鸡蛋
LeetCode887.鸡蛋掉落建筑有n层(取值1,2,...n),存在一个楼层F(0原创 2022-07-15 17:35:46 · 978 阅读 · 0 评论 -
算法学习笔记——动态规划:戳气球
LeetCode312.戳气球数组nums中,保存了每个气球上的数字,戳破一个气球,得分是(若越界,认为两个边界上有数值为1的虚拟气球)可以按照不同顺序戳破气球,问所能得到的最高分数如nums=[3,1,5,8],返回167([3,1,5,8]-->[3,5,8]-->[3,8]-->[8]-->[])...原创 2022-07-15 17:35:31 · 462 阅读 · 0 评论 -
算法学习笔记——动态规划:正则表达式匹配
LeetCode 10. 正则表达式匹配给你一个字符串 s 和一个正则表达式 p('.'匹配任意字符 ,'*'让其前一个字符出现0次/任意次) ,判断两者是否匹配例如,输入s = "aab" p = "a*b",返回Trueclass Solution: def isMatch(self, s: str, p: str) -> bool: s_len = len(s) p_len = len(p) # dp[i][j] 表示 s[i:.原创 2022-07-15 17:35:21 · 365 阅读 · 0 评论 -
算法学习笔记——动态规划:最小编辑距离
s1=“horse”,s2=“rose”,返回2(horse->rorse->rose)希望把字符串s1转化为s2,一次操作可以选择插入/删除/替换,求完成转换的最少操作次数。套路两个字符串的动态规划,一般都需要二维dp数组,i、j分别与两个字符串挂钩。我们固定s2,然后解决如何从s1转化为s2的问题(两者反过来其实也一样)注意,实际应该在dp数组左侧和上侧多插入一个空白行,使用。LeetCode72.编辑距离。...原创 2022-07-15 17:35:11 · 1083 阅读 · 0 评论 -
算法学习笔记——动态规划:求满足条件的最长子数组
通过枚举[以每一个元素为结尾的子数组]来完备的枚举所有子数组,用dp数组在每一步维护所需的指标最优。在nums数组中找出一个具有最大乘积的连续子数组(最少包含一个元素),返回其最大乘积。在nums数组中找出一个具有最大和的连续子数组(最少包含一个元素),返回其最大和。在nums数组中,求出其所有元素乘积为正数的最长子数组的长度。LeetCode1567.乘积为正数的最长子数组长度。LeetCode918.环形子数组的最大和。LeetCode152.乘积最大子数组。...原创 2022-07-15 17:18:06 · 202 阅读 · 0 评论 -
算法学习笔记——动态规划:不连续取值的前提下求最大总和
LeetCode 198. 打家劫舍一排房屋,某房屋内的金额数为nums[i],相邻房屋内的钱不能被同时取出,求最多能取出多少钱nums=[1,1,3,4],返回5(选择取出1+4=5)dp[i]代表对于0~i号房屋,能取走的最大金额依次考虑每个房屋,显然每次只有两种选择:dp[i] = max(dp[i - 1], dp[i - 2] + nums[i])若要取出当前房屋的钱,则不能拿取前一个房屋的钱若不取出当前房屋的钱,则可以拿取前一个房屋的钱(当然,前一个房屋同样可以选择拿或不拿).原创 2022-07-15 17:17:55 · 318 阅读 · 0 评论 -
算法学习笔记——动态规划:构造回文串最少插入次数、最长回文子序列问题
返回让s成为回文串的最少插入次数,如s=“mcadm”,返回2,因为插入2次可将字符串可变为“mcdadcm”或者“mdcacdm”可见,每次计算dp[i][j],依赖于左、左下、下方的三个格子,所以要注意dp表的计算顺序从下往上、从左往右计算。,然后再来插入另一个字符(后面这次插入是免不掉的,因为首位字符不同,至少插入一次才有回文串)显然,对于回文串,左边有一个字符,右边就应该有一个同样的字符。显然,对于回文串,左边有一个字符,右边就应该有一个同样的字符。由于每次计算dp[i][j],......原创 2022-07-15 17:11:49 · 511 阅读 · 0 评论 -
算法学习笔记——动态规划:最长回文子串
给出字符串s,求s的最长的回文子串用dp[i][j]表示从下标i到j的子串是否为回文串初始化:dp[i][i]为True复杂度O(n)原创 2022-07-15 17:11:32 · 249 阅读 · 0 评论 -
算法笔记——动态规划:最长递增子序列LIS、二维LIS问题
LIS(Longest Increasing Subsequence)问题是一个经典的动态规划问题思路:实现:只求解长度的代码:能够打印具体最长递增子序列的代码:二分查找优化效率如果不关心序列的内容,只需要求最长递增子序列的长度,那么,另外一种思路是:实现:只求解长度的代码:能够打印具体最长递增子序列的代码:变种:二维LIS问题预处理并转化问题:最终需要求长、宽都单调递增的最长子序列,是二维LIS问题,可以先将长度递增排列,再求出宽度的最长递增子序列即可(转化为一维LIS问题)注意细节:原创 2022-07-12 11:15:32 · 505 阅读 · 0 评论 -
算法学习笔记——动态规划:最长公共子串LCS、最长公共子序列LCS
给出两个字符串str1和str2,求他们的最长公共子串最长公共子序列LCS给出两个序列x,y,找出他们的最长公共子序列LCS(Longest Common Subsequence)与最长公共子串的区别在于,子串必须是多个相连的字符,而子序列不一定思路:实现:......原创 2022-07-12 11:02:42 · 395 阅读 · 0 评论 -
算法学习笔记——动态规划:核心思想与求解步骤
动态规划本质就是将问题拆分为子问题+穷举,但不是暴力穷举,其思想源于暴力穷举,但使用了“备忘录”或DP Table进行优化,从而利用子问题解决大问题,此外再无奥妙可言(思考如何穷举->追求聪明地穷举)动态规划三要素:重叠子问题、最优子结构、状态转移方程找状态转移方程,核心问题就是状态、选择、DP数组的定义思考问题的base case(最简单情况)是什么思考问题有什么“状态”,即子问题中的变量思考对于每个状态,有什么“选择”使状态改变ps. 技巧:类比数学归纳思想,假定已知dp[0]..原创 2022-07-12 10:33:59 · 435 阅读 · 0 评论 -
算法学习笔记——动态规划:概述(动态规划的要素、动态规划与DFS/BFS/贪心算法的区别)
动态规划Dynamic Programming,DP问题动态规划问题一般形式就是求最值(最长递增子序列、最小编辑距离)其本质就是穷举,但不是暴力穷举,其思想源于暴力穷举,但使用了“备忘录”或DP Table进行优化,此外再无奥妙可言(思考如何穷举->追求聪明地穷举)ps. 以后看到求最值问题,养成条件反射:首先思考如何穷举所有可能结果动态规划三要素:重叠子问题、最优子结构、状态转移方程有重叠子问题决定了动态规划与暴力穷举的不同,动态规划能使用“备忘录”或DP Table进行优化具原创 2022-07-12 10:29:01 · 1394 阅读 · 0 评论 -
算法学习笔记——数据结构:哈夫曼树、带权路径长度WPL、哈夫曼编码
树的带权路径长度WPL最小的树为哈夫曼树,本文介绍哈夫曼的构造和应用原创 2022-07-12 10:20:12 · 2487 阅读 · 0 评论 -
算法学习笔记——数据结构:栈(处理括号表达式、四则运算计算器)
思路:思路:类似上一题,但是这里的后面如果为2,则原来化学式内部的所有原子数都要乘二,另外不同化学式的原子数量还要合并,因此使用计数器解决这题,合并操作用即可方便的完成前两题不一定要用到栈,而这题的四则运算特性与栈完美切合:...原创 2022-07-11 21:42:00 · 304 阅读 · 0 评论 -
算法学习笔记——常用技巧:滑动窗口与前缀和思想结合(求子数组数量问题)
关于数组的连续区间的问题,应条件反射想到滑动窗口和前缀和技巧利用左右指针,在一次遍历中求解题目使用滑动窗口(双指针)解决的问题多与「最小」、「最大」有关,这是因为我们可以在满足条件的前提下,尽可能维护最长的窗口例如:LeetCode 3. 无重复字符的最长子串;(VIP)LeetCode 209. 长度最小的子数组;LeetCode 76. 最小覆盖子串;(209题的升级版)LeetCode 159. 至多包含两个不同字符的最长子串;(VIP)LeetCode 424. 替换后的最长重复字符(⭐原创 2022-07-11 21:40:54 · 581 阅读 · 0 评论 -
算法学习笔记——常用技巧:差分数组
差分是前缀和和的逆过程(类比求导与积分)如果需要将区间内的所有元素的值增加,可以拆分为两部分操作:差分数组模板题思路:原创 2022-07-11 21:39:01 · 301 阅读 · 0 评论 -
算法学习笔记——常用技巧:前缀和
前缀和用于解决数组中的[不同区间的和]的大量查询核心思路是把多个不同区间的问题,统一为相同类型的子问题也就是把[左右界不固定的问题] 转化为两个 [左边界固定,右边界不定]的问题区间和的查询:给出一个数组,多次查询不同区间的区间和类似前缀和,【区间的异或运算】也能通过【前缀异或】来得到,因为与之前同样的,有二维的前缀异或问题...原创 2022-07-11 21:38:33 · 260 阅读 · 0 评论 -
算法学习笔记——常用技巧:双指针(滑动窗口算法)
解决问题时直接套入模板,只需考虑下面四个问题并修改相应的细节:暴力列举所有子串,复杂度O(N^2)以上使用滑动窗口算法解题,时间复杂度O(N)开始前,先考虑上面的四个问题:套入模板即可,另外本题的技巧是:用solved表示当前窗口内有几个字母的数量符合要求(window[ch]>=need[ch]),若solved==len(need),则当前窗口满足要求,注意在扩大和缩小窗口时更新solvedS是否包含T的全排列暴力方法是穷举T的所有全排列,然后在S中搜索,然而计算全排列需要阶乘级别的复杂度转化为原创 2022-07-11 21:36:45 · 210 阅读 · 0 评论 -
算法学习笔记——常用技巧:双指针(二分搜索)
下面是基本代码框架,后面所有写法都是它的变形这里用语句列举出所有情况,以便思路清晰,弄懂后可以用写出更简化的版本如果所用语言有整型溢出问题,那么mid的计算改为,防止溢出下面有两种不同写法:和,两种写法是等效的,主要区别在于,搜索区间是还是二分搜索逻辑框架1.基本二分搜索只要找到了目标值,即,直接返回下标mid即可如果while循环终止,此时,相当于搜索区间为空,意味着没找到,返回-1这个算法用于数组中每个元素只出现一次的情况如果目标数字出现多次,返回的是“靠中间”的那个下标只需修原创 2022-07-11 21:35:58 · 363 阅读 · 0 评论 -
算法学习笔记——常用技巧:双指针(快慢指针和左右指针)
数组、链表、子串相关的题目,常考虑使用双指针技巧- **快慢指针**用于**链表**判断成环、在链表归并排序时找中点- **左右指针**用于**数组字符串**问题,一般是左右两端相向而行,如二分搜索、反转数组、两数之和问题- 更深入的是**滑动窗口算法**,严格来说它属于快慢指针在数组字符串上的应用,用于解决**字符串匹配**问题......原创 2022-07-11 21:33:35 · 407 阅读 · 0 评论 -
算法学习笔记——数据结构:优先队列/堆(TopK问题)
堆是自带排序功能的数据结构,其本质是完全二叉树,但为了方便,用数组存储;在使用过程中,保证任意父节点的值一定大于或等于/小于或等于子节点,Python中用`heapq`库来实现堆原创 2022-07-11 21:28:04 · 242 阅读 · 0 评论 -
算法学习笔记——数据结构:树状数组BIT
问题2的分析:树状数组是一种动态维护前缀和(支持单点修改+区间查询)的数据结构记原数组为,其前缀和数组表示区间元素的总和总结: = + ,可以不断递归求解,直到i=0理解:总结:更新后,下一个受影响并需要更新的是,可以不断递归求解,直到理解:思路:实际上我们只关注元素之间的大小关系,因此在这里等价于因此,我们要做的就是把具体数值映射到排名,从而回到上面的 [正整数序列]的问题具体实现:可见,离散化的优点:将不在合适范围内的整数/非整数映射为正整数,或者将分布稀疏的元素聚集到一起,总之就是将元素值映射原创 2022-07-11 21:24:06 · 329 阅读 · 0 评论 -
算法学习笔记——数据结构:二叉搜索树BST
二叉搜索树BST二叉搜索树BST,即BinarySearchTree,其特性是:对于任意节点,如果其值为val,则左子树所有节点值小于等于val,且右子树所有节点值大于等于val注意利用此特性,避免多余的访问 def traverseBST(node: TreeNode, target: int): """BST遍历框架""" if node is None: return if node.val == target:原创 2022-04-03 21:21:18 · 293 阅读 · 0 评论 -
算法学习笔记——数据结构:二叉树(结点数、反序列化、最近公共祖先LCA)
二叉树BinaryTree总体框架:二叉树算法设计的框架:关注当前节点要做什么,左右子树交给递归框架,不用当前节点操心一旦涉及建树、修改等操作,函数最终应该返回TreeNode节点,并且接收递归调用的返回值(赋值给节点的左右子树)完全二叉树、满二叉树完全二叉树CompleteBinaryTree:每一层都紧靠左侧排列满二叉树PerfectBinaryTree:每层都是满的求节点个数:对于一般二叉树,遍历所有节点对于满二叉树,求出深度d,节点总数为2^d-1对于完全二叉树,其原创 2022-04-03 21:21:06 · 715 阅读 · 0 评论 -
算法学习笔记——数据结构:并查集Union-find Set
并查集(UnionFindSet)并查集(UnionFindSet)用于维护多个集合之间的关系,其名称显示了其功能,它提供了三个API:合并:合并两个集合(只需从不同集合中分别给出两个元素即可)查找:查看两元素是否属于同一集合集合:维护多个集合的关系,查询当前有多少个独立的集合并查集常可应用与图的有关问题,因为它与图中连通分量的概念相关:例如在遍历树/图的过程中,需要不断将两个不同的连通分量连接合并在一起,最后求一共有几个连通分量/求两元素是否属于同一连通分量等并查集的实现并查集的核心原创 2022-03-24 17:14:11 · 537 阅读 · 0 评论 -
算法学习笔记——数据结构:LRU和LFU(有序字典LinkedHashMap和有序集LinkedHashSet的Python实现)
算法不能脱离数据结构,各种炫酷的算法本质上都是将基本的数据结构进行组合,本文研究链表、二叉树等基本的数据结构能“玩”出什么花样HashMap:基于哈希表的 Map 接口的实现HashMap=数组+链表,数组是主体,链表用于解决哈希冲突不看底层实现,HashMap就是一个(用链表解决哈希冲突的)散列表,在Python中就是字典哈希链表LinkedHashMap与LRU算法LRU缓存淘汰算法,全称LeastRecentlyUsed,即认为最近使用的数据是最有用的,在生活中的例子就是手机后台任务:.原创 2022-03-24 17:13:17 · 2144 阅读 · 0 评论 -
算法学习笔记——数据结构:栈(判断括号合法性、找出非法括号)
栈是一种后进先出(Last In First Out,LIFO)的数据结构,只能从一个方向插入或删除思路:把握好以下性质,用回溯生成括号序列即可实现:维护当前已使用的左括号数量和右括号数量,回溯生成括号序列(在合法时尝试添加左/右括号)判断括号合法性如果只有一种括号,可以不使用栈,从左向右遍历字符串:遇到,left+=1遇到,若left>0,left-=1(用左括号与之匹配),否则说明没有左括号可以匹配,是非法序列遍历完后,检查如果left!=0,则有未配对的左括号,同样是非法的情况对于原创 2022-03-24 17:08:10 · 1242 阅读 · 0 评论 -
算法学习笔记——特殊数据结构:单调队列
单调队列Monotonic Queue单调队列本质上就是队列,但在使用队列的过程中,程序逻辑保证队内的元素是单调的(单调递增或单调递减,视具体情况而定)用于维护一段区间(滑动窗口)的最大值/最小值(或更一般的,某个序列只有首尾元素变动,维护该序列的最值)具体做法是入队时,删除一些队尾元素从而保证入队后整个队列单调另外,由于队首队尾都需要出队操作,这就要求使用双端队列collections.dequeLeetCode 239. 滑动窗口最大值给定长度的窗口在一个数组中逐位滑动,求在各个位置原创 2022-03-23 00:12:43 · 290 阅读 · 0 评论 -
算法学习笔记——特殊数据结构:单调栈
单调栈单调栈本质上就是栈,但在使用栈的过程中,程序逻辑保证栈内的元素是单调的(单调递增或单调递减)这听起来有点像堆heap,但实际上单调栈用途不广泛,多用于处理典型的问题:下一个更大元素(Next Greater Element)问题单调栈模板下一个更大元素:给出一个数组,返回一个等长数组,其中各索引出存储着原数组的该处元素的下一个更大元素(不存在则为-1),例如,输入[2,1,2,4,3],返回[4,2,4,-1,-1]如何用O(n)复杂度解决问题?(相当于只线性扫描一遍数组)思路:把原创 2022-03-20 23:24:37 · 720 阅读 · 0 评论 -
算法学习笔记——底层数据结构:哈希表、列表、集合
查找速度的比较数组中保存着许多数据['apple','banana',...'milk',...'lemon']如果希望找到'milk'的位置(下标index),有以下几种查找方式简单查找:O(n),相当于数据都是无序的,需要一个一个对比,看当前的数据是否是目标数据二分查找:O(log2n),数据有序排列,每次将数据分为两半,提高查找效率散列表:O(1),对于要查找的数据,用散列函数直接映射为一个独一无二的数字,这个数字就是目标数据的存储位置(下标index),这样可以直接取出数据散列函数必须满原创 2022-03-18 21:06:28 · 1063 阅读 · 0 评论 -
算法学习笔记——整体学习路径与框架思维
数据结构的存储方式数据结构的底层存储方式只有数组(顺序存储)和链表(链式存储)数组是紧凑连续存储,相对节约空间,可以索引快速访问,但如果连续内存空间不够则需要将数据复制到一块更大的空间中,扩容复杂度O(N),插入删除也需要移动大量元素,复杂度O(N)链表的元素不连续,不存在扩容问题,插入删除复杂度O(1),但不能随机访问,且存储前后元素的指针要消耗额外空间数组和链表是一切的底层基础,其他任何数据结果都是上层建筑图的两种表示:邻接矩阵就是二维数组,但在稀疏图中耗费空间;邻接表就是链表,节省空间原创 2022-03-18 20:58:35 · 583 阅读 · 0 评论