链表
文章平均质量分 52
Noric!
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
114 二叉树展开为链表
题目中已经明确,要用先序遍历的顺序展开,那么就需要按照“中-左-右”的顺序遍历二叉树,剩下的问题在于如何在遍历过程中完成链表指针的更新。由于“右子节点”需要链接到左子树最后一个节点之后,所以需要额外的指针。,并对左子树展开,展开完成后,将原右半部分添加到当前遍历的末尾。记录已展开链表的末尾。由于链表按照前序遍历的方式展开的,所以。,都需要对链表进行展开,具体将左子树移动到。原创 2024-12-16 23:57:01 · 210 阅读 · 0 评论 -
146 LRU缓存
的优先级在O(1)内提高呢?首先,这个数据结构要是有序的,且它任意元素的删除和插入要在O(1)复杂度内完成。因此排除数组、队列、堆栈等,剩下链表作为一个不错的选择。现在,我们可以通过map快速定义到,待更新元素的位置。但要将链表中的元素删除,需要知道上一个节点才行,因此我们的链表不能是单向的,而是双向的。代码实现中,记得将双向链表元素删除、插入封装成函数,可以使代码更精简一些。如何选择合适的数据结构,将访问过的<可以利用Map,实现O(1)内<的形式就可以解决这道题了。要有O(1)时间复杂度。原创 2024-12-08 23:39:00 · 587 阅读 · 0 评论 -
148 排序链表
时间复杂度内解决问题,满足这个条件的常用排序算法有:快速排序(Quick Sort)、归并排序(Merge Sort)和堆排序(Heap Sort)。为空之外,链表内只有一个元素的情况也要返回,不然会陷入死循环。为空的情况,返回时也要注意返回。,快速找到链表中间的节点;使用自定义节点做一个伪。递归的终止条件,除了。原创 2024-12-08 23:04:19 · 695 阅读 · 0 评论 -
19 删除链表的倒数第N个结点
题目要求删除倒数第N个结点,并且返回头结点,就很适合利用递归的方法解决。递归既有前向的过程也有逆向的过程,本题中只需利用其逆向过程,找到倒数第N个结点,并返回该节点下一个节点的地址,即可完成删除。返回的节点地址应作为上一个节点。原创 2024-10-30 14:12:01 · 218 阅读 · 0 评论 -
2 两数相加
这道题可以用模拟很直观的解决,模式加法的计算过程,只不过套了一层链表的外衣。题目给出的数字在链表中是按照。排列的,即链表头节点的值代表相加数字的个位,这样只需要从链表头开始计算加法即可得到最终的结果。不为0,需要进位,需要额外在末尾添加一个节点。需要注意的是,最后遍历完两个链表之后,如果。原创 2024-10-23 23:43:05 · 375 阅读 · 0 评论 -
142 环形链表II
判断链表是否有环,当快慢指针相等时,链表中存在环。但环形链表II在其基础上,额外需要找到环的第一个节点,可以在快慢指针相遇的基础上,进一步分析。此时,如果使用两个指针分别从表头和相遇点开始移动,则这两个指针会相遇于环开始的节点,此时返回结果即可。如果链表存在环,则快慢指针相遇于环上一点(如下图),将链表拆分成。原创 2024-10-21 22:48:23 · 945 阅读 · 0 评论 -
141 环形链表
存在环的条件下,如何证明两指针一定会享相遇呢?最容易想到的方法,就是遍历链表同时用哈希表。但能不能更进一步优化空间复杂度到。如果链表不存在环,则。为所有自然数,所以一定能够到达。遇到重复节点则认为存在环,返回。这种方法简单直接,时间复杂度。会在环中绕圈,直到某一时刻与。,则链表中不存在环,返回。- 为链表中环的长度。借用双指针的思路,用。每次前进1步,快指针。原创 2023-12-12 22:29:24 · 217 阅读 · 0 评论 -
234 回文链表
由于链表的结构特点,访问链表中的元素的时间复杂度为O(n)。相比较而言,使用数组会方便很多,实现O(1)访问。所以这个题,可以先遍历一遍把数值存到数组中,再使用双指针判断是否是回文。原创 2023-12-05 22:22:57 · 224 阅读 · 0 评论 -
206 反转链表
用于重复将当前节点添加到链表末尾,被函数各层调用使用,一开始的思路是,是用全局变量去存储链表末尾,并在每次操作后不断更新。:通过函数调用其自身,完成目标。另外需要注意的点,由于每次操作是重复的,如果仅仅改变指针的指向会导致反转后的链表未能指向。现在,函数递归到节点2,如何找到翻转链表的末尾?思路大致相同,但是能否优化无需使用全局变量来存储链表末尾?,用于题目输出,只能作为递归函数的返回值传递。,因此在每一步操作中,需额外将反转链表末尾指向。2)目标拆解后,函数每一步需要。,作为翻转后链表的表头。原创 2023-12-04 21:54:49 · 210 阅读 · 0 评论 -
160 相交链表
相交,则它们之间的区别就仅在于相交节点之前的部分(其实任意两个链表最终都会相交,最坏相交于NULL节点)。这个思路虽然可行,但略显繁琐。对于不同的情况需要分类讨论,因而导致代码写起来非常复杂。如果在相交前,到达了链表末尾,则下一节点将是另一条链表的起始节点。3、较长的链表经过差值处理后,遍历两链表检查是否存在相交点。的距离相等,指针能同时到达。这种交叉遍历的方式,巧妙兼容了。,若两链表不相交,两指针最终一定会同时到达。两个链表,直到它们遇到相交节点(1、找到两个链表较长的那个;,若相交,相交节点到。原创 2023-11-27 22:01:56 · 202 阅读 · 0 评论 -
Leetcode160 相交链表
本题解决方法也有两种:哈希表、双指针。哈希表:记录从一个 head 开始经过的节点存入表中;遍历另一个 head,遇到重复节点返回。双指针:虽然路径a、b的长度可能不同,但其路径之和一定相等 a+b = b+a。针对这一点,记录两个指针,分别从两个路径头开始移动,速度均为1,若走到链表尽头 nullptr 则再从另一个路径头开始移动,若两个指针相遇,即返回。由于路径之和相等,若两链表相交,则指针会在相交点相遇;若两链表不相交,指针最后则会同时指向空指针。附上代码:哈希表class Solut..原创 2021-12-10 14:07:00 · 1072 阅读 · 0 评论 -
Leetcode148 排序链表
题目要求时间复杂度O(nlogn)O(n\log{n})O(nlogn),空间复杂度O(1)O(1)O(1) 对链表排序,自然可以想到快速排序或者归并排序的方法,但是在链表中从后往前访问不太方便,所以选择了归并排序(merge sort)的方法。思想:递归地将链表从中间分成左右两部分,从下向上将两个链表合并成有序地链表。链表分开的方式,有两种:记录链表的大小 nnn,移动指针进行分割(n2\frac{n}{2}2n,n−n2n - \frac{n}{2}n−2n)快慢指针。快指针移动速度为.原创 2021-12-09 16:58:25 · 160 阅读 · 0 评论 -
Leetcode146 LRU缓存机制(哈希表+双向链表)
O(1)O(1)O(1) 时间复杂度可以通过哈希表+双向链表来实现哈希表存储 <key, node ptr>,可以在 O(1)O(1)O(1) 时间内找到对应key值的节点。双向链表节点内存储{key,value,prev,next}四个属性。每个节点的插入、删除操作都可以在常数时间完成。链表中有固定的head, tail节点,最近访问的节点移动到tail之前,最不常访问key值对应的节点则位于head之后。因此,每次访问只需要改变节点的位置,完成常数时间的更新。附上代码:struct.原创 2021-12-08 21:30:12 · 196 阅读 · 0 评论 -
Leetcode142 环形链表II(map+快慢指针)
本题与环形链表I类似,区别在于需要返回环开始的第一个节点。附上代码:快慢指针:class Solution {public: ListNode *detectCycle(ListNode *head) { if(!head || !head->next) return nullptr; ListNode* fast = head->next; ListNode* slow = head; while(fast !=.原创 2021-12-07 18:31:04 · 338 阅读 · 0 评论 -
Leetcode141 环形链表
解决方法有两种:遍历链表,在map中记录遍历过的节点,遇到重复的返回true快慢指针,快指针移动速度为2,慢指针移动速度为1。如果存在环,快慢指针会相遇。否则会走到空指针。附上代码:哈希表class Solution {public: bool hasCycle(ListNode *head) { map<ListNode*,int> m; ListNode* node = head; while(node &&.原创 2021-12-04 15:25:04 · 179 阅读 · 0 评论 -
Leetcode234 回文链表(递归/反转)
解决这道题的方法有三种:遍历链表得到所有值的数组,用双指针判断【时间复杂度 O(N)O(N)O(N) 空间复杂度 O(N)O(N)O(N)】利用递归判断【时间复杂度 O(N)O(N)O(N) 空间复杂度 O(N)O(N)O(N)】反转链表判断【时间复杂度 O(N)O(N)O(N) 空间复杂度 O(1)O(1)O(1)】附上代码:递归class Solution { ListNode* comp;public: bool recurr(ListNode* head){ .原创 2021-12-03 17:31:46 · 285 阅读 · 0 评论 -
Leetcode206 反转链表(迭代+递归)
迭代思想:记录当前节点 curr 和上一个节点 prev。遍历链表,不断将 curr->next 指向 prev。把当前节点放到上一节点的前面。递归思想:递归函数返回的已经排序的列表有特点:out -> node1-> node2 -> ... -> nodex -> nullptrhead -> nodex -> nullptr因此,不需要遍历返回的链表找到最后一个节点,head 的指向就是最后一个节点。注意:head -> nex.原创 2021-11-30 13:30:58 · 176 阅读 · 0 评论 -
Leetcode 二叉树展开为链表
非递归的方法:若 root 左子树非空,则找到左子树的最右节点,将右子树接到右节点再将左子树移到根节点的右节点上,root 不断更新成右节点,最后得到输出/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(.原创 2021-08-03 22:28:09 · 148 阅读 · 0 评论 -
Leetcode 合并K个升序数组
三种方法:暴力,两两排序:时间复杂度 O(k2n)O(k^2n)O(k2n),空间复杂度 O(1)O(1)O(1)分治排序:时间复杂度 O(k2n)O(k^2n)O(k2n),空间复杂度 O(1)O(1)O(1)堆排序:时间复杂度 O(k2n)O(k^2n)O(k2n),空间复杂度 O(1)O(1)O(1)附上代码:分治排序:/** * Definition for singly-linked list. * struct ListNode { * int val; * .原创 2021-08-03 00:05:03 · 580 阅读 · 0 评论 -
Leetcode 删除链表倒数第N个节点
双指针能够实现:时间复杂度 O(N),空间复杂度 O(1);且只用一次遍历就能得到答案。思想就是,先让一个指针 iii 移动,移动n步后,另一个指针 jjj 跟着移动,直到 iii 到达终点,则 jjj 所指的节点,即为需要删除的节点的上一个节点。若删除的是头节点,则找不到相关的上一个节点,此时 n>0n>0n>0 特殊处理下。附上代码:/** * Definition for singly-linked list. * struct ListNode { * int.原创 2021-08-02 18:48:01 · 117 阅读 · 0 评论 -
Leetcode 合并有序列表的两种方法:递归+迭代
递归和迭代的区别,感觉就在于递归是 函数的嵌套迭代是 用for循环遍历【递归】:优点就是代码简洁,很短。/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} .原创 2021-08-02 18:46:21 · 253 阅读 · 0 评论 -
Leetcode 链表 两数之和
结构体访问成员变量时用.,例如head.val指针访问成员变量时用->,例如current->val写链表时,应使用 new 的初始化方法:ListNode* head = new ListNode();空指针nullptr 可以用if(pointer)判断这道题思路比较简单,可以用一个变量sum解决进位问题,空间复杂度O(1)./** * Definition for singly-linked list. * struct ListNode { * int val;.原创 2021-08-02 16:03:42 · 150 阅读 · 0 评论
分享