数据结构&LeetCode
文章平均质量分 72
常用数据结构的使用
晓晓纳兰容若
Notes do not lie!
展开
-
Leetcode笔记--腾讯精选练习50题
通过队列取余的方式存储每一位数值,存储所有位的数值后,遍历队列更新结果。注意,-1, ..., -9对10取余还是等于本身。可以借鉴整数反转的思路,通过整数反转重建数字,如果重建的结果与原来的数字相等,则为回文数;类似于归并排序,只不过需要额外考虑进位的问题。遍历每一个字符,从中心向外扩展;5--字符串转换整数(atoi)5--字符串转换整数(atoi)2--寻找两个正序数组的中位数。原创 2022-03-17 22:14:50 · 32 阅读 · 0 评论 -
Leetcode刷题笔记--Hot91--100
状态转移方程:dp[j] += dp[j - nums[i]],其实质是:当背包已经装了nums[i]时,剩余容量为 j - nums[i],此时装满剩余容量的方法数为 dp[j - nums[i]],遍历不同的 nums[i] 将方法数相加即可;的总结点数,例如上图中[4, 2, 1, 3]可以理解为以 1 为根节点,其左子树路径的最大结点数为[4, 2],右子树路径的最大结点数为[3];递归二叉树,对于每一个节点,递归求解左子树的结点数,右子树的结点数,向上返回最大的节点树;7--合并二叉树(617)原创 2023-10-31 15:26:17 · 226 阅读 · 0 评论 -
Leetcode刷题笔记--Hot81--90
原地修改数组,遍历数组,根据数组的值修改对应原数组索引的值,具体对应关系是 1对应坐标0,2对应坐标1;转化成0 - 1背包问题,一半的子集和vec作为背包容量,另一半的子集和作为物品,只需判断最后 dp[vec] 是否等于 vec 即可;基于从下到上的 dp 回溯法,每一个节点只有两种状态,dp[0]表示被打劫,dp[1]表示不被打劫;当前节点不被打劫时,其孩子可以都被打劫,也可以都不被打劫,或者一个被打劫另一个不被打劫。这道题使用 0-1 背包问题的 1 维解法时,需要先正序遍历物品,再。原创 2023-10-27 15:29:45 · 235 阅读 · 0 评论 -
代码随想录笔记--单调栈篇
当某一个元素比当前栈顶元素大时,计算以该栈顶元素为中心的接雨水面积:area = (当前遍历元素的索引 - 栈顶元素栈中前一个元素的索引)* min(当前遍历元素的高度 - 栈顶元素的高度,栈顶元素栈中前一个元素的高度 - 栈顶元素的高度)维护一个单调递减的单调栈(从栈顶开始),对于每一个柱子,寻找左右两边比其高度矮的柱子,计算其构成的矩形面积: area = (当前遍历元素的索引 - 栈顶元素在栈中上一个元素的索引 - 1)* 当前栈顶元素的高度;代码随想录 ended in 2023.10.24!原创 2023-10-23 14:13:29 · 176 阅读 · 0 评论 -
Leetcode刷题笔记--Hot71--80
定义dp[i][0]表示第 i 天处于买入状态,dp[i][1]处于卖出状态,dp[i][2]处于冷冻期状态。初始化dp[0][0] = -prices[0],dp[0][1] = 0, dp[0][2] = 0;原创 2023-10-22 13:58:31 · 240 阅读 · 0 评论 -
Leetcode刷题笔记--Hot61-70
状态转移方程: dp[i][j] = std::min(dp[i-1][j-1], std::min(dp[i-1][j], dp[i][j-1])) + 1;不断将剩余先修课程数为0的课程加入到队列q中,当队列为空时,若修的课程数等于总课程数,则返回true,否则返回false;遍历两遍,第一遍求解L[i],L[i]表示第i位左边所有数的乘积;基于动态规划,dp[i][j]表示以(i, j)为右下角,所构成正方形的最大边长。每修队列q中的课程,以该课程作为先修课程的所有课程,其剩余先修课程个数减1;原创 2023-10-14 20:59:20 · 289 阅读 · 0 评论 -
Leetcode刷题笔记--Hot51-60
当一个桶不为空时,当准备放入一个新的元素时,如果新的元素与桶内的元素不相同,则不放入这个新元素且将桶内的一个元素拿出来;状态转移方程 dp[i][0] = dp[i-1][1] + nums[i],dp[i][1] = dp[i-1][0];之所以使用 dp_min[i],是由于会出现负数的情况,当负负得正时会出现更大的连续和,因此要考虑 dp_min[i];访问到第i间房屋时,设dp[i][0]表示打劫第i间房屋,dp[i][1]表示不打劫第i间房屋,能够获得的最高金额;非常有哲学意义的一道题!原创 2023-09-24 19:56:06 · 372 阅读 · 0 评论 -
数据结构笔记--背包问题
状态转移方程:dp[i][j] == std::max(dp[i-1][j], dp[i-1][j-weight[i]] + value[i]),其中 dp[i-1][j] 表示不选择物品 i,dp[i-1][j-weight[i]] + value[i] 表示选择物品 i;状态转移方程:dp[j] = std::max(dp[j], dp[j - weight[i]] + value[i]),其中 dp[j - weight[i]] + value[i] 表示选取物品 i 时;原创 2023-09-23 14:37:07 · 243 阅读 · 0 评论 -
代码随想录笔记--动态规划篇
当 word1[i-1] 不等于 word2[j-1] 时,dp[i][j] = std::min(dp[i-1][j-1] + 1, std::min(dp[i-1][j] + 1, dp[i][j-1] + 1));当s[i] = t[j] 时,dp[i][j] = dp[i-1][j-1] + dp[i-1][j];初始化:dp[0][0] = 0,dp[0][1] = -prices[0],dp[0][2] = 0,dp[0][3] = -prices[0],dp[0][4] = 0;原创 2023-09-21 14:26:56 · 490 阅读 · 0 评论 -
代码随想录笔记--贪心算法篇
用哈希表记录每一个字母最远出现的位置,然后遍历字符串,记录遍历区间中字母的最远位置,当遍历位置到达区间字母的最远位置时,表明包含了区间中所有的字母,记录区间的大小;再从右到左遍历,当一个孩子比右边的孩子高时,贪心地只多分发一个糖果(相对于右边的孩子),一个孩子分发的糖果取决于上述两个遍历过程的最大值;基于贪心算法,从左到右遍历,当一个孩子比左边的孩子高时,贪心地只多分发一个糖果(相对于左边的孩子);对区间进行排序,让尽可能多的区间重叠在一起,判断重叠区间的个数,移除重叠区间,返回结果即可;原创 2023-09-13 00:10:25 · 372 阅读 · 0 评论 -
Leetcode刷题笔记--Hot41-50
采用二叉树深度递归搜索,对于每一个结点,其最大路径和可能为以下四种情况:cur + cur->left, cur + cur->right, cur, cur + cur->left + cur->right;根据前序遍历的顺序,遍历二叉树,使用一个指针表示当前遍历到的节点的前驱节点,例如图中 2 的前驱节点是 1,4 的前驱节点是 3(根据前序遍历);对于本题需要将同一层的节点放在一个数组中,因此遍历的时候需要用一个变量 nums 来记录当前层的节点数,即 nums 等于队列元素的数目;原创 2023-09-06 22:09:35 · 413 阅读 · 0 评论 -
代码随想录笔记--回溯算法篇
因为有重复的元素,因此需要在树层上进行去重,树层去重需要判断当前元素是否在遍历之前出现过,如果出现过则舍弃;基于回溯法,暴力加入子串,判断每一个子串是否是一个回文子串,如果不是回文子串则跳过,否则继续,直到将字符串的所有字符都遍历完;需要注意的是,本题需要去重,因此采用类似组合问题的去重逻辑:先对数组进行排序,再进行树层上的去重;根据传入的字符串,遍历每一个数字字符,基于回溯法,递归遍历每一个数字字符对应的字母;基于回溯法,暴力遍历加入每一个元素,每加入一个元素就收获一次结果;原创 2023-09-06 19:29:01 · 713 阅读 · 0 评论 -
代码随想录笔记--二叉树篇
即后序遍历的最后一个节点是根节点,因此可以根据根节点来划分中序遍历,将其划分为左子树和右子树,再根据左右子树的大小来划分后序遍历,递归构建二叉树;循环出栈处理节点,并将右孩子和左孩子存在栈中(右孩子先进栈,左孩子再进栈,因为栈先进后出,这样可以确保左孩子先出栈,符合根→左→右的顺序);⑤ 删除节点的左右均不空,记录删除节点的左孩子,然后递归删除节点的右孩子,找到最左边的叶子节点,将原先记录的删除节点的左孩子放到叶子结点的左孩子中;对于小于左边界的节点,则其左子树所有节点都会小于左边界,因此可以舍弃;原创 2023-09-02 12:56:56 · 646 阅读 · 0 评论 -
代码随想录笔记--栈与队列篇
基于栈,遇到左括号,入栈对应的右括号。遇到右括号,判断当前栈顶元素是否与右括号相等,相等则表示之前曾遇到对应的左括号,表明匹配成功并弹出栈顶元素,否则返回 false;当移动滑动窗口时,需要判断当前移出窗口的元素是否是队头元素,如果是则需先将队头元素弹出(因为该元素已经离开了滑动窗口,相当于失效);基于栈,遍历字符串数组,当遇到数字时将数字压入栈中,当遇到运算符时,将栈顶的两个元素取出来进行运算,并将运算结果重新压入栈中;基于栈,遍历字符串,判断当前字符与栈顶元素是否相同,相同则弹出栈顶元素,否则入栈;原创 2023-09-01 16:35:53 · 1174 阅读 · 0 评论 -
代码随想录笔记--字符串篇
不使用辅助空间,要求空间复杂度为O(1);首先使用快慢指针剔除多余的空格,接着反转所有字符,最后对单词的字符进行再次反转;遍历提取每一个有效的单词,存储在一个栈中,最后遍历栈连接字符串即可;空间复杂度为O(N);双指针算法,交换两个指针的字符;以 2k 个字符为一组进行遍历;3--反转字符串中的单词。2--反转字符串II。5--重复的子字符串。原创 2023-08-31 14:19:12 · 413 阅读 · 0 评论 -
代码随想录笔记--哈希表篇
利用哈希表存储,key 为 target - nums[i],value 为 i;遍历数组判断当前nums[i]是否在哈希表中出现,返回匹配的两个结果对应的索引即可;利用哈希表,其中key为两个数组对应元素的和,value为出现的次数;接着遍历剩下两个数组的元素和是否在哈希表中出现,记录出现的次数即匹配结果;利用哈希表存储数组1的元素,接着遍历数组2并判断元素是否存储在哈希表中,将交集元素存储并返回;类似于三数之和,只需额外多遍历一次,同时注意剪枝和去重的操作;2--两个数组的交集。原创 2023-08-30 12:38:32 · 341 阅读 · 0 评论 -
代码随想录笔记--链表篇
在链表相关题目中,常新定义一个虚拟头结点 dummynode 来指向原链表的头结点,当需要返回链表时,只需返回 dummynode->next;当快慢指针第一次相遇后,慢指针从头出发,快指针从第一次相遇的节点出发,快慢指针均每次走一步,当下一次相遇时就处于环的入口节点,返回即可;快慢指针,快指针每次走两步,慢指针每次走一步,根据快慢指针是否相遇判断是否有环;快慢指针,当链表有环时,快慢指针必定相遇;5-1--删除链表倒数第N个节点。4--两两交换链表中的节点。5-3--环形链表II。原创 2023-08-29 14:18:28 · 589 阅读 · 0 评论 -
代码随想录笔记--数组篇
由于数组包含负数,则平方后的数组符合:大→小→大的排列规律;可以利用双指针算法从两端向中间遍历,取最大值放在结果数组(提前开辟);等于号 = 放在哪个条件判断的依据:当 arr[mid] == target 时,应该往哪一边继续二分寻找;等于号 = 放在哪个条件判断的依据:当 arr[mid] == target 时,应该往哪一边继续二分寻找;2-2--寻找最后一个等于目标值的位置。2-1--寻找第一个等于目标值的位置。3-1--快慢指针移除元素。3-2--有序数组的平方。2--二分查找法进阶。原创 2023-08-28 13:24:20 · 423 阅读 · 1 评论 -
Leetcode刷题笔记--Hot31-40
对于 i 个数字,选定不同的数字 head 作为根节点,则左子树的节点数为 head - 1,对应的二叉搜索树数目为 dp[head - 1],右子树的节点数为 i - head,对应的二叉搜索树数目为 dp[i - head];对于每一根柱子 i,找到最左边比它高度低的柱子,记为 left[i],同理找到最右边比它高度低的柱子,记为 right[i];遍历每一行,以当前行为底,将列看成柱子,遍历每一根柱子,类似于上题,寻找基于该柱子的最大矩形(利用单调栈向左向右寻找比当前柱子矮的边界);原创 2023-08-25 20:27:03 · 1697 阅读 · 0 评论 -
数据结构笔记--实现简单并查集算法
并查集的核心功能有两个:第一个是判断两个元素是否属于同一个集合;第二个是合并两个元素,使其处在同一集合中;原创 2023-08-23 16:13:07 · 70 阅读 · 0 评论 -
Leetcode刷题笔记--Hot21-30
当 word1[i]!= word2[j] 时,dp[i][j] = min(dp[i-1][j-1]+1, dp[i-1][j]+1, dp[i][j-1]+1);初始状态:dp[0][0] = grid[0][0],上边界dp[0][j] = dp[0][j-1] + grid[0][j],左边界dp[i][0] = dp[i-1][0] + grid[i][0];状态转移方程:dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j];原创 2023-08-22 23:46:43 · 378 阅读 · 0 评论 -
数据结构笔记--哈希表的相关应用(RandomPool结构,布隆过滤器和一致性哈希算法)
使用两个哈希表 indexKeymap 和 keyIndexmap 来存储(key, index) 和 (index, key),其中index从0开始连续增长,与哈希表的大小有关;① insert(key):将某个 key 加入到结构中,并做到不重复加入;③ getRandom():等概率随机返回结构中的一个key;② delete(key):移除结构中的key;要求:以上三种功能的时间复杂度都是 O(1);1--RandomPool结构。1--RandomPool结构。原创 2023-08-18 19:22:19 · 186 阅读 · 0 评论 -
数据结构笔记--字符串经典高频题
利用全排列遍历字符串,注意重复字符在树层上的剪枝(但要保留重复字符在树枝上的排列)老实人做法,按规律顺序填入 board 中;返回一个字符串的全部子序列(包括空串);暴力枚举是否加入当前字符;1--打印字符串的全部子序列。1--打印字符串的全部子序列。2--字符串的全排列。原创 2023-08-15 18:11:11 · 110 阅读 · 0 评论 -
数据结构笔记--优先队列(大小根堆)经典题型
输入:正数数组 costs,costs[i] 表示项目 i 的花费;正数数组 profits,profits[i] 表示项目 i 的花费;当小根堆值的数量与大根堆值的数量相差 2 时,从小根堆弹出数据添加到大根堆中,保持两个根堆的容量差不超过;分别使用大根堆和小根堆存储数据,每添加一个数据,先将数据添加至大根堆,再将数据弹出并添加到小根堆;每次从小根堆解锁项目添加到大根堆中,优先做大根堆利润最高的项目;小根堆存储所有项目,大根堆存储可以进行的项目;1--项目的最大利润。1--项目的最大利润。原创 2023-08-14 14:28:39 · 173 阅读 · 0 评论 -
数据结构笔记--前缀树的实现
前缀树的每一个节点拥有三个成员变量,pass表示有多少个字符串经过该节点,end表示有多少个字符串以该节点结尾,nexts表示该字符串可以走向哪些节点;本题不能自定义节点,因此将 pass、end 和 nexts 等成员变量转换成类的成员变量,新节点就是类的对象;2-1--实现Trie(前缀树)2--LeetCode真题。原创 2023-08-14 12:20:46 · 135 阅读 · 0 评论 -
数据结构笔记--二叉树经典高频题
递归寻找目的结点,当找到目的结点后往上返回目的结点,否则返回 NULL;最近祖先只有两种情况:① 自底向上,当两个目的结点分别在当前结点的左右子树时,当前结点为两个目的结点的最近祖先;② 最近祖先与其中一个目的结点相同,则另一个目的结点在目的结点的子树上;如果 p 结点没有右子树,则从 root 结点开始寻找 p 结点的父亲结点;利用前序遍历或层次遍历等方式进行序列化,再根据不同遍历的方式来设计反序列化的方式,利用反序列化重构二叉树;如果 p 结点有右子树,则返回其右子树最左边的结点(中序遍历的定义);原创 2023-08-12 23:23:38 · 342 阅读 · 1 评论 -
数据结构笔记--常见二叉树分类及判断实现
层次遍历二叉树的节点,当遇到第一个节点(其左右儿子不双全)进行标记,往后遇到的所有节点应均为叶子节点,当遇到一个不是叶子节点时,返回 false 表明二叉树不是完全二叉树;递归自底向上判断是否是一颗搜索二叉树,返回判断结果的同时,要返回对应的最小值和最大值;递归自底向上判断是否是一颗满二叉树,返回判断结果的同时,要返回对应的深度和节点数;递归自底向上判断是否是一颗平衡二叉树,返回判断结果的同时,要返回对应的深度;搜索二叉树的性质:左子树的节点值都比根节点小,右子树的节点值都比根节点大;原创 2023-08-12 12:27:04 · 313 阅读 · 0 评论 -
数据结构笔记--前序、中序和后序遍历的递归与非递归实现
③ 出栈结点的左儿子入栈1,出栈结点的右儿子入栈2;② 出栈结点的右儿子入栈,出栈结点的左儿子出栈;流程:初始化两个栈,根节点入其中一个栈1,另一个栈2用于收集;⑤ 收集栈的结点依次出栈,此时顺序为后序遍历;③:对出栈结点的右子树执行第 ① 步操作;① 结点出栈,处理结点;②:结点出栈,处理结点;前序遍历顺序:根结点、左子树、右子树;后序遍历顺序:左子树、右子树、根节点;1--前序、中序和后序遍历的递归实现。1--前序、中序和后序遍历的递归实现。① 栈1的结点出栈;流程:初始化一个栈,根节点入栈;原创 2023-08-10 20:10:50 · 390 阅读 · 0 评论 -
数据结构笔记--链表经典高频题
题目:给定一个单链表的头结点head,结点的值类型是整型,再给定一个整数pivot,实现一个调整链表的的函数,将链表调整为左部分都是值小于pivot的结点,中间部分都是值等于pivot的结点,右部分都是值大于pivot的结点;与反转单向链表类似,使用 pre,cur 和 next 指向前一个节点,当前节点和后一个节点,不断遍历更新三个指针所指向的节点即可,并修改对应的前驱指针和后驱指针;面试做法可以参考反转单向链表,将链表反转,与原链表的结点进行比较即可,当反转链表与原链表的结点不相等,表明不是回文链表;原创 2023-08-09 21:58:17 · 575 阅读 · 0 评论 -
数据结构笔记--归并排序及其拓展题(小和问题、逆序对问题)
实例,给定数组 [1, 3, 4, 2, 5],1 左边比 1 小的数,没有;3 左边比 3 小的数, 为 1;4 左边比 4 小的数, 为 1 和 3;2 左边比 2 小的数,为 1;5 左边比 5 小的数,为 1, 3, 4 和 2;因此数组的小数和为:1 + (1+3) + (1) + (1+3+4+2) = 16;在归并排序两两比较两个数组的元素时,就确定对应的小数和;归并排序的核心思想:将一个无序的序列归并排序为一个有序的系列;起来,叫做这个数组的小和,请编码实现求解一个数组的小和;原创 2023-08-06 22:30:38 · 279 阅读 · 0 评论 -
剑指offer刷题笔记--Num61-68
1--扑克牌中的顺子(61)1--扑克牌中的顺子(61)原创 2023-08-02 00:19:25 · 311 阅读 · 0 评论 -
剑指offer刷题笔记--Num51-60
考虑到题目给定的数组是递增有序的,因此可以考虑使用双指针法,分别指向数组的左右两端,并计算双指针指向值的和,当和小于 target 时,左指针右移,当和大于 target 时,右指针左移,当和等于 target 时,返回结果;出现三次的数字,在二进制位中其对应位肯定是 3 的倍数,因此只需统计 32 位整型中 1 出现的次数,并将其整除 3,就可以得到只出现1次的数字在该位的数值;相同的两个数进行异或,其结果为零(与顺序无关),因此在题目的数组中,遍历所有元素进行异或,得到的最终结果为。原创 2023-07-19 17:51:31 · 1113 阅读 · 0 评论 -
剑指offer刷题笔记--Num41-50
使用快排对字符串数组进行排序,要确保由字符串数组组成的数最小,即strs[0]strs[1]strs[2]...最小,必须连续满足strs[0] < strs[1], strs[1] < strs[2];基于无序哈希表,key为字符,value 为该字符是否唯一,遍历字符串,当字符唯一时,value 设为 true,否则设为 false;转移方程:dp[i][j] = grid[i][j] + max(dp[i-1][j], dp[i][j-1]);维护两个优先队列,Q1大数优先,存储比中位数小的数;原创 2023-07-10 01:45:07 · 449 阅读 · 0 评论 -
数据结构笔记--十大经典排序算法(C++)
经过一次遍历之后,pivot 左边的元素都比 pivot 小,pivot 右边的元素都比 pivot 大,这样对于最终的结果来说,pivot 所在的位置是排好序的,只需递归排序 pivot 左边的元素和右边的元素即可;希尔排序是插入排序的进阶版,实质上是使用多次插入排序,只是每次插入比较的步长是step,当 step 为1时,希尔排序就退化为普通的插入排序;希尔排序的时间复杂度为:O(n^(1.3--2)),是一种不稳定的排序;进阶归并排序将一个无序的序列归并排序为一个有序的系列;原创 2023-07-08 14:10:17 · 704 阅读 · 0 评论 -
Leetcode刷题笔记--Hot11-20
从尾开始遍历,找到第一个 a[j] > a[i] 的位置,交换 a[j] 和 a[i],并将 a[i] 之后的数据反转,使其变成升序;基于二分法,二分后肯定有一边是有序的,因此首先判断哪一边是有序,接着继续判断target是否在有序部分,如果不在则下一次二分的范围是无序部分;与归并排序两个有序链表的思想类似,可以用 k 个结点指针指向 k 个链表的结点,每次归并值最小的结点到链表中,同时结点下移;利用栈,遍历字符串,遇到左括号则入栈,遇到右括号则出栈,并判断出栈元素是否与右括号匹配;原创 2023-07-05 21:09:46 · 398 阅读 · 0 评论 -
剑指offer刷题笔记--Num31-40
直观思路:用两个指针 i 和 j 指向压入和弹出的 vector,终止条件是:所有元素都压入了辅助栈(i > len),且辅助栈当前的栈顶元素与弹出的元素 popped[j] 不相等;模拟栈的压入顺序,依次压入 pushed 里的所有元素,用一个指针 j 指向需要弹出的元素,当符合弹出要求时就弹出对应的元素;二叉搜索树的定义:左子树的结点均小于根节点,右子树的结点均大于根结点;,不同的是为了打印每一层的结点,需要循环当前层的结点数次,每一次。,因此只需要循环队列的长度次,并记录对应的结点值即可;原创 2023-07-04 13:54:07 · 445 阅读 · 0 评论 -
剑指offer刷题笔记--Num21-30
想象成环形链表,反转链表的实质上结点指向上一个结点,则只需遍历链表,将当前结点指向上一个结点,不断更新当前结点和上一个结点即可;由于左右指针的间距为k,则左指针指向原链表的倒数第 k 个节点,直接返回即可;双指针法,左指针从 0 开始遍历,直到遇到偶数,右指针从 len - 1 开始遍历,直到遇到奇数;递归判断左子树的左子树与右子树的右子树是否相等,左子树的右子树与右子树的左子树是否相等;这时左指针指向偶数,右指针指向奇数,交换两个指针的数值,并继续判断下一组数;4--合并两个排序的链表(25)原创 2023-06-26 17:34:44 · 415 阅读 · 0 评论 -
Leetcode刷题笔记--大数取余
则 a^n % p = [(a % p) * a^(n-1) % p] % p,用一个变量 res 记录当前的 a^(n-1) % p,循环计算和更新 res;指数 n 为奇数时(用 n % 2 == 1 为 true 判断),先将一个 a 提出来与当前结果相乘,再将底数与自身相乘,最后将指数 n 整除 2;n为奇数时,a^n%p = [(a%p)(a^(n-1)%p)]%p;n为偶数时,a^n%p = (a^2 % p)^(n//2)%p;给定大数 a^n,返回其对 p 取余的结果,即 a^n % n;原创 2023-06-08 19:04:43 · 290 阅读 · 0 评论 -
数据结构笔记--KMP算法的实现
str: abcbab → next: 0 0 0 0 1 2 (即当前字符 next 数组的后缀包括当前字符本身,且规定第0个字符的前缀为0,从第1个字符开始构建next数组);原创 2023-06-04 15:43:26 · 136 阅读 · 0 评论 -
Leetcode刷题笔记--Hot01-10
基于滑动窗口和哈希表,用一个滑动窗口遍历字符串的字符,确保滑动窗口内的所有字符都是不重复的,当滑动字符不断扩大遇到重复字符时,将左指针右移,直到没有重复字符,这时比较滑动窗口的长度和最大长度的值,更新最大长度;使用双指针法,左指针指向左边的容器,右指针指向右边的容器,左容器容量低则左指针自增,右容器容量低则右指针自减,直到两个指针相遇,记录并更新最大容量值,具体原理证明见上面的讲解视频;遍历字符串的每个字符,用两个指针 l 和 r 分别指向其左字符和右字符,判断左字符和右字符是否相等,不断贪心向外扩展;原创 2023-05-31 01:20:32 · 509 阅读 · 0 评论