
数据结构与算法
文章平均质量分 54
数据结构与算法
秀秀_heo
一个学习前端开发的大学生,博客为自己的学习笔记,仅供个人学习使用。
展开
-
【数据结构与算法】力扣 5. 最长回文子串
这个方法利用了回文串的对称性质,通过。进行扩展,找到最长的回文子串。,更新最大回文子串的范围。中最长的 回文子串。来查找最长的回文子串。原创 2025-02-03 10:49:01 · 640 阅读 · 0 评论 -
【期末速成】算法
不稳定排序:排序后相对位置不变(多个相同的数)。稳定排序:时间复杂度比较:综合推荐:特点:基本要素:解题步骤:构建哈夫曼树:对于带权连通图G(每条边上的权均为大于零的实数),可能有多棵不同生成树。每棵生成树的所有边的权值之和可能不同。其中权值之和最小的生成树称为图的最小生成树。生成树的顶点数 - 1 = 边数 。其中,普利姆算法和克鲁斯卡尔算法都是用于构造最小生成树的。算法思想:时间复杂度普里姆(Prim)算法克鲁斯卡尔(Kruskal)算法适用范围:使用 迪杰斯特拉算法:最长公共子序列(Longe原创 2025-01-23 17:59:10 · 606 阅读 · 0 评论 -
【数据结构与算法】力扣 23. 合并 K 个升序链表
使用一个递归的 helper 帮助我们将多个链表逐步拆分为两个。两个解决了,那么 K 个也就解决了。但如果将多个改为合并两个,想必大家都会做了。依次比较两个链表的每一个节点,把它们连接起来即可。那么多个不会,两个一眼就能想到解决办法的这部分问题,可以采用一个通用思想:分治!请你将所有链表合并到一个升序链表中,返回合并后的链表。给你一个链表数组,每个链表都已经按升序排列。合并多个升序数组,乍眼一看这?除了分治,我们还有什么其他方法吗?原创 2024-10-29 21:28:36 · 560 阅读 · 0 评论 -
【数据结构与算法】力扣 143. 重排链表
不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。贴上我乱糟糟的笔记供后续复习。:将链表拆分为前后两部分,以。原创 2024-10-28 16:22:44 · 504 阅读 · 0 评论 -
【数据结构与算法】力扣 92. 反转链表 II
这道题和反转链表的唯一不同是它存在起始和结束位置,所以我们只需要在原有反转链表的基础上,再思考一下如何将反转后的小链表和之前的链表连接起来,也就是需要多思考两个指针(next)的指向。除此之外,如果需要反转三个数据。部分反转循环代码块执行两次(反转两次);而全部反转循环代码块执行三次(反转三次,有一次 null 头节点)。这样看来,只是三四代码语句有区别,而这两句代码正好对应了我上面说到的那两次不同的指针改变。原创 2024-10-28 15:21:38 · 474 阅读 · 0 评论 -
【数据结构与算法】力扣 46. 全排列
其核心思想是尝试构建一个解的过程,逐步推进,并在发现当前部分解无法生成一个完整解时,进行回溯,即撤销最近的选择,然后尝试其他可能的选择。一般回溯的逻辑放在递归函数的下面。这是一种效率低纯暴力的解法,且没有其它的更好的解法。很明显这是一道排列问题,遇到排列问题,最先想到的应该就是回溯算法。给定一个不含重复数字的数组。原创 2024-10-21 16:58:30 · 376 阅读 · 0 评论 -
【数据结构与算法】力扣 59. 螺旋矩阵 II
定义边界变量使用topbottomleft和right四个变量来表示当前矩阵的边界。top表示当前未填充区域的最上边行索引,bottom表示最下边行索引。left表示未填充区域的最左边列索引,right表示最右边列索引。这些边界变量随着螺旋填充或遍历逐渐收缩,直到遍历完成整个矩阵。按照顺时针方向遍历或填充按照顺时针的顺序进行:从左到右(填充top行),从上到下(填充right列),从右到左(填充bottom行),从下到上(填充left列)。每次填充后,相应地缩小边界(如top++原创 2024-10-19 16:25:28 · 751 阅读 · 0 评论 -
【数据结构与算法】力扣 54. 螺旋矩阵
给你一个 行 列的矩阵 ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。示例 1:示例 2:提示:定义四个边界:循环遍历矩阵:遍历矩阵: 和 的作用: 的作用: 的作用:复杂度分析原创 2024-10-19 15:50:49 · 414 阅读 · 0 评论 -
【数据结构与算法】力扣 42. 接雨水
分别记录从左边和右边柱子的最大高度。通过比较两边的最大高度,确定当前位置能够接到多少水。原理就是水由左右两个高度最大的值来维护,而真正计算水又通过这二者间的小值来计算。的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。我们使用左右两个指针来遍历数组,维护两个变量。个非负整数表示每个宽度为。这种解法的时间复杂度是。,因为只使用了常数空间。原创 2024-10-12 08:30:18 · 555 阅读 · 0 评论 -
【数据结构与算法】力扣 455. 分发饼干
就这道题而言,sFlag 不一定每次循环都需要移动(因为可能最小的饼干满足不了最小胃口的孩子,所以需要加大饼干,而孩子还是不变),而 gFlag 只是起到一个循环遍历的作用,所以用 for + if 或者 while + if 都可以。而 while 更像是 if 版本的循环, while 加上了判断的功能,并且可以循环遍历。假设你是一位很棒的家长,想要给你的孩子们一些小饼干。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。一眼贪心,尽量使用越小的饼干投喂胃口越小的孩子,使得利用率达到最大。原创 2024-08-17 19:52:14 · 188 阅读 · 0 评论 -
【数据结构与算法】力扣 49. 字母异位词分组
lodash 里面自带一个方法,可以根据规则对字符串数组进行分组,而分组后的 value 刚好是我们需要的结果。当然不用 lodash 也可以,我们自己实现一个分组,相当于把以上 lodash 的原理实现了一遍。是由重新排列源单词的所有字母得到的一个新单词。可以按任意顺序返回结果列表。给你一个字符串数组,请你将。原创 2024-05-14 14:52:15 · 320 阅读 · 1 评论 -
【数据结构与算法】力扣 222. 完全二叉树的节点个数
的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。你可以设计一个更快的算法吗?遍历树来统计节点是一种时间复杂度为。,求出该树的节点个数。原创 2024-05-14 14:49:34 · 325 阅读 · 0 评论 -
【数据结构与算法】递归
注意防止栈溢出(函数调用就是通过栈这种数据结构实现的),需要有结束条件。理论上所有递归都可以用循环实现。原创 2024-05-12 21:39:09 · 515 阅读 · 1 评论 -
【数据结构与算法】力扣 111. 二叉树的最小深度
如果将根节点当做叶子节点,那和求最大深度没什么区别,只是将却左右子树最大值改为求最小值。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。首先一个可能犯错的点,根节点肯定不是叶子结点。这道题用前序、后序、迭代都可以求。给定一个二叉树,找出其最小深度。叶子节点是指没有子节点的节点。原创 2024-05-12 21:36:38 · 482 阅读 · 0 评论 -
【数据结构与算法】力扣 226. 翻转二叉树
而最好使用前后序遍历,中序有点复杂。当然层序和非递归遍历也可以。,翻转这棵二叉树,并返回其根节点。给你一棵二叉树的根节点。比较简单,就是一个递归。原创 2024-05-08 14:32:12 · 454 阅读 · 0 评论 -
【数据结构与算法】力扣 102. 二叉树的层序遍历
队列中只要有元素,就需要循环遍历。为了将当前层的元素添加到 temp 当前层的数组中。而循环的次数刚好就是当前 queue 的长度(当前层元素个数)。将旧的(当前层元素)推入 temp,将新的(子节点)添加到 queue。输出为一个二维数组,所以需要一个 res 作为最终结果数组,需要一个个的 temp 作为每一层的数组。注:需要先保存一下 length 因为 在获取子节点的时候会改变 queue.length。(即逐层地,从左到右访问所有节点)。那么如何控制元素的遍历条件呢?上图来自:代码随想录。原创 2024-05-07 19:02:36 · 479 阅读 · 2 评论 -
【数据结构与算法】力扣 144.前序遍历,145.后序遍历,94.中序遍历
递归算法很简单,你可以通过迭代算法完成吗?递归算法很简单,你可以通过迭代算法完成吗?递归算法很简单,你可以通过迭代算法完成吗?给你一棵二叉树的根节点。给定一个二叉树的根节点。原创 2024-05-05 09:34:40 · 423 阅读 · 0 评论 -
【数据结构与算法】力扣 347. 前 K 个高频元素
相同元素都对应一个出现次数,可以很容易想到 map。key, value 代表元素和出现的次数。然后就可以不断(k 次)遍历 比较 value,并把 key 加入结果数组中。,请你返回其中出现频率前。你所设计算法的时间复杂度。这里使用优先级队列来解决。原创 2024-05-04 13:38:46 · 467 阅读 · 0 评论 -
【数据结构与算法】堆
堆是是一个完全二叉树,其中每个节点的值都大于等于或小于等于其子节点的值。这取决于是最大堆还是最小堆。小根堆:每个根都小于子节点。大根堆:每个根都大于子节点。【从堆的定义到优先队列、堆排序】 10分钟看懂必考的数据结构——堆_哔哩哔哩_bilibili。原创 2024-05-04 13:38:15 · 927 阅读 · 2 评论 -
【数据结构与算法】力扣 239. 滑动窗口最大值
而这道题我们需要维护的就是最大值,是队尾元素,也是我们最终需要存放到结果队列中的元素。要保持始终队尾元素是最大值,因为维护其他元素没有意义(不是我们要求的)。而因为我们需要找到每一个滑动窗口的最值,所以就需要使用单调队列(维护一个队列的单调性)。单调队列的应用场景就是滑动窗口问题。**的滑动窗口从数组的最左侧移动到数组的最右侧。此时的滑动窗口就很像是一个队列,所以可以直接把它当做一个队列来分析解答。当滑动窗口不再覆盖的元素(队尾元素),需要直接弹出。依次找到每一个窗口中的最大值,添加到结果数组中。原创 2024-05-01 13:28:02 · 369 阅读 · 0 评论 -
【数据结构与算法】力扣 1047. 删除字符串中的所有相邻重复项
思路也很简单了,和之前做的括号匹配思路相同,不再赘述了。在完成所有重复项删除操作后返回最终的字符串。在 S 上反复执行重复项删除操作,直到无法继续删除。会选择两个相邻且相同的字母,并删除它们。给出由小写字母组成的字符串。原创 2024-04-30 20:17:31 · 365 阅读 · 0 评论 -
【数据结构与算法】力扣 150. 逆波兰表达式求值
注意:向零截断指的是在整数除法中舍弃小数部分的行为。当两个整数相除时,结果会截断为最接近零的整数。这意味着如果结果为正数,则向下取整,如果结果为负数,则向上取整。逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面。返回一个表示表达式值的整数。总体思路就是栈的运用。原创 2024-04-30 20:14:56 · 633 阅读 · 0 评论 -
【数据结构与算法】力扣 20. 有效的括号
上面代码直接看会发现我在匹配到左括号的时候,并没有直接将左括号放入栈中,而是将右括号放入栈中;这是为了当我们遍历到右括号 的时候,可以直接进行字符的比较,而不是再次进行左右括号的匹逻辑,简化了过程!还有一点注意,当我们右括号多了的时候,此时 s[i] 会与 arr[-1] 进行比较,也就是 s[i] 与 undefined 进行比较,为 false,所以也是可行的。然后就是依次放入栈中,遇到匹配的弹出的过程了。括号匹配问题,直接用栈来解决!,判断字符串是否有效。原创 2024-04-29 09:32:21 · 270 阅读 · 0 评论 -
【数据结构与算法】力扣 225. 用队列实现栈
和之前做的用栈实现队列,基本思路差不多。都是根据不同数据结构的特性控制元素的移动。请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(你能否仅用一个队列来实现栈。原创 2024-04-28 21:52:30 · 470 阅读 · 0 评论 -
【数据结构与算法】力扣 232. 用栈实现队列
由于插入是在 arr2, 所以先查找 arr2 是否有元素,有就直接 shift 出去,没有从 arr2 先 shift -> push 到 arr1,然后在 shift 出去。(左右的 pop 和 shift 是需要实现的方法)所以在 arr1 为空的时候,需要先把 arr2 的所有元素全部放入 arr1 中,以满足顺序问题。(左右的 pop 和 shift 是需要实现的方法)插入的操作都在 arr2,取出的操作都在 arr1,因此主要难点在于连接 arr1 和 arr2 的思路。原创 2024-04-27 14:10:28 · 484 阅读 · 0 评论 -
【数据结构与算法】力扣 459. 重复的子字符串
在本段代码中,我们利用next数组的最后一个值,来判断字符串是否是由重复的子串组成的。既然是由重复的子串构成的,那么该字符串的首尾子串一定是相等的。它使用了双指针的方法来遍历字符串s,并根据不同的情况更新指针和next数组的值。通过计算next数组,就能得到字符串中最长的重复子串的长度。所以我们的思路是:将两个字符串拼起来,找这个二倍的字符串是否含有原字符串(去掉首尾,防止两个原字符串的干扰)。重复的子串连接成父串?这段代码主要运用了KMP算法中的next数组计算来判断字符串是否由重复的子串组成。原创 2024-04-26 22:16:29 · 949 阅读 · 1 评论 -
【数据结构与算法】力扣 151. 反转字符串中的单词
中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。先除去字符串两边的若干空格,再用若干空格分割字符串为数组。最后逆置数组元素输出。如果字符串在你使用的编程语言中是一种可变数据类型,请尝试使用。中使用至少一个空格将字符串中的。之间用单个空格连接的结果字符串。是由非空格字符组成的字符串。原创 2024-04-22 09:05:27 · 224 阅读 · 0 评论 -
【数据结构与算法】力扣 541. 反转字符串 II
abcd” 为一组,满足 2k,反转"ab",“efg” 为一组,满足 k < length < 2k,反转 “ef”。但但是,我用的是 js,直接反转 reverse 方法,不是对原字符串进行操作,而是 copy 一个操作完进行返回,赋值给其他变量。然后因为还有一些不变的字符,需要再对他们进行拼接,就有一些麻烦。最后层循环 i 可以用来限定范围的起始点,然后范围的总长度为 2k,因为条件就是 i += 2 * k。当然,由于这里的左右指针还是左闭右开的,在遍历交换的时候还需要注意交换的是 r - 1。原创 2024-04-22 09:04:23 · 538 阅读 · 0 评论 -
【数据结构与算法】力扣 344. 反转字符串
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组。修改输入数组**、使用 O(1) 的额外空间解决这一问题。不要给另外的数组分配额外的空间,你必须**那就要双指针交换了。原创 2024-04-19 13:35:57 · 441 阅读 · 2 评论 -
【数据结构与算法】力扣 15. 三数之和
然后 i -> 2位置, l -> 3位置,r -> 4位置,[-1, -1, 2] 和之前的冲突,需要去重,这轮 i 循环直接 continue。(题干说明:输出的顺序和三元组的顺序并不重要,所以可以排序),i 为起始位置,l 左指针,r 右指针。也就是说 i 和 left 相等是允许的,也就是说 i 和 i + 1 是可以相等的,所以应该采用 i 和 i - 1 来去重。首先抛出一个难点,此时我们遍历到第 i 个元素,想要去重,那是应该判断 i 和 i + 1 还是 i 和 i - 1 呢?原创 2024-04-14 11:40:34 · 599 阅读 · 0 评论 -
【数据结构与算法】力扣 454. 四数相加 II
然后比较难理解的是 preTwoSum.get(0 - sum) ,这是因为 需要下面的 双重 for 循环里的 sum 刚好加上 preTwoSum 也就是上面双重 for 循环的 sum 之和为 0。而因为 map 的 key 都是 sum,value 为出现 sum 的个数,所以采用 get 和 set 来进行四数之和的运算和判断。陷入深思,想想之前做过的题,有一个求两数之和的,当时可以使用暴力,也可以使用 map。这道题和两数之和的题很好诠释了 map 这种数据结构的使用。一看题,四个数之和?原创 2024-04-11 00:14:11 · 382 阅读 · 0 评论 -
【数据结构与算法】力扣 1. 两数之和
难点是需要想到此时的key 用来存放 值,而不再是 索引index。因为需要找到两个 key 相加为 target,而需要返回的是 index 索引。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。整数,并返回它们的数组下标。你可以按任意顺序返回答案。,请你在该数组中找出。利用数据结构 map。原创 2024-04-10 13:01:15 · 362 阅读 · 0 评论 -
【数据结构与算法】力扣 349. 两个数组的交集
看到唯一,可以直接想到用 Set。然后思路嘛,没什么难的,直接上代码。输出结果中的每个元素一定是。,返回 *它们的 *就是一些简单点的写法。原创 2024-04-10 12:31:17 · 301 阅读 · 0 评论 -
【数据结构与算法】力扣 242. 有效的字母异位词
主要思路:就是在 arr 中放26个位置,值全为0。然后遍历 s,在 a-z 的对应位置加 1,然后遍历 t,在 a-z 的对应位置减 1,所以 s 和 t 相同的话,那么所有位置应该还是 0。比较字符串内字符的个数相同,很容易想到将各个字符作为一个key 存入一个对象中,个数相同就是这些键值是否相同。此时会发现存在一个问题:那就是key 的顺序不同也会导致判断不同。所以判断是否相同时需要先将key进行排序。中每个字符出现的次数都相同,则称。这种类似于暴力解答,直接进行判断。,编写一个函数来判断。原创 2024-04-09 10:42:54 · 757 阅读 · 0 评论 -
【JavaScript】作用域和闭包
是当前代码段中,所有的变量(变量、函数、形参、arguments)组成的一个对象。在js中,函数存在一个隐式属性[[scopes]],这个属性用来保存当前函数的执行上下文环境,由于在数据结构上是链式的,因此也被称作是作用域链。我们可以把它理解为一个数组,可以理解为是一系列的AO对象所组成的一个链式结构。JavaScript采用词法作用域,也就是静态作用域。作用域链的变量只能向上访问,直到访问到 window 对象终止。作用域链执行完会销毁。之所以没有及时被垃圾回收机制回收,是因为作用域链没有断裂。原创 2024-04-08 16:41:46 · 558 阅读 · 0 评论 -
【数据结构与算法】力扣 142. 环形链表 II
比如使快指针一次移动两个节点,慢指针一次移动一个节点,当进入环中,慢指针一定会在某个时刻追上快指针。所以当 n 为 1 的时候, x = z。代表着如果有一个节点在相遇处,一个节点在head处,他们同时出发,刚好会在环形入口节点处相遇。指针再次到达,则链表中存在环。为了表示给定链表中的环,评测系统内部使用整数。n 表示相遇的时候,快指针已经在环内转的圈数。如果链表中有某个节点,可以通过连续跟踪。,返回链表开始入环的第一个节点。,仅仅是为了标识链表的实际情况。如果链表无环,则返回。,则在该链表中没有环。原创 2024-04-08 16:41:16 · 485 阅读 · 0 评论 -
【数据结构与算法】力扣 19. 删除链表的倒数第 N 个结点
所以思路就是找一对双指针 fast 和 slow,他们在维持一定的位移差的情况下同时移动,fast 一直指到 null(尾),而 slow 刚好是 fast 后面的第 n + 1 个元素,第 n 个刚好是要删除的元素。所以我的思路就是先将倒序转化为正序,用正序的思路去删。如果正序为第 x 个,倒序为第 n 个,那么找找规律就可以发现。为了方便,依旧是引入虚拟头节点,既然要删第 x 个,那么就去找第 x - 1 个。大家可以想一想,倒数第 n 个和正序的第 n 个有什么相同之处捏?再看一眼:哎呦不对!原创 2024-04-07 18:13:21 · 457 阅读 · 0 评论 -
【数据结构与算法】力扣 24. 两两交换链表中的节点
现在顺序问题总算说完了,下一个难点是节点会丢失,这里我使用了 temp 和 temp1 来保存节点,以避免这个问题。它需要每两个节点和他们后面的下一个(也就是第三个节点)发生关系(指向),所以可以考虑引入一个虚拟头节点进行操作。给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。先以 1 -> 2 -> 3 为例,操作过后为 2 -> 1 -> 3,而 cur 先指向 1,然后指向了 2,之后还会指向 1,所以现在就成了 dummyHead,cur,cur.next 这三个节点的指向不断改变。原创 2024-04-06 15:08:53 · 450 阅读 · 0 评论 -
【数据结构与算法】力扣 206. 反转链表
双指针 pre 和 cur,不断移动 pre 和 cur(二者同时移动),使得 cur 指向 pre。temp 的作用是防止 cur.next 丢失。先说整体思路:既然要翻转,也就是指针的指向改变。那么就可以让后一个指向自身,自身再指向null。而且每一个节点都是相同的操作,直接使用递归即可解决。上面使用了递归的操作。下面我们讲讲使用双指针的写法。注意要先移动 pre,否则 cur 的值会发生改变。,请你反转链表,并返回反转后的链表。原创 2024-04-06 15:08:22 · 247 阅读 · 0 评论 -
【数据结构与算法】力扣 707. 设计链表
我要往这里添加 node,但发现前一个 node 连不过来(找不到了),好吧,我先找找前一个node -get 方法返回的是 val,不便于我们后续使用,所以在自己写一个 getNode 方便直接获取节点。一般情况,获取 index 前一个 node,指向 index 后一个 node 直接删掉。使用虚拟头节点方便操作,不改变原链表,以便在需要时返回头节点或者某个节点。特殊情况处理:插入后也只有一个节点,那么头尾都是 新节点。直接使用虚拟头节点的方式插入头节点。特殊情况,处理原本没有尾的情况。原创 2024-04-05 16:36:45 · 897 阅读 · 0 评论