链表
s
baixiaofei567
如果十年前没种树,那最好的时间是现在
展开
-
203. 移除链表元素
看似不难其实麻烦,设置一个虚拟头结点是关键。记得将虚拟节点和然后就是双指针,一个前一个后,分情况讨论。法一:设置虚拟节点后将其和head相连,因为我们不会每一次都将pre->next指向cur。如果是val,就让pre->next=cur->next,cur往后,pre别往后,因为不保证下一个cur就是正常的,可能下一个还是val,所以pre不能这么快更新。如果不是val,就把pre更新为cur,cur继续更新。/** * Definition for singly-linked.原创 2021-06-05 23:56:30 · 211 阅读 · 1 评论 -
两个链表生成相加链表
可以参考大数相加,只不过加上了链表反转的思想,总的来说就是模板题class Solution {public: /** * * @param head1 ListNode类 * @param head2 ListNode类 * @return ListNode类 */ ListNode* addInList(ListNode* head1, ListNode* head2) { // write code here.原创 2021-04-16 00:47:55 · 162 阅读 · 0 评论 -
109. 有序链表转换二叉搜索树
和有序数组建BST基本一样多了几道复杂的工序罢了,左右边界通过链表走到空来确定,不是用l和r了。用快慢指针来确定mid结点。然后再次遍历,将slow的前一个结点指向nullptr,这个很重要。当head为空就是递归边界返回null即可class Solution {public: TreeNode* sortedListToBST(ListNode* head) { //通过快慢指针将链表切分,递归构造左右子树 //递归边界是l>r的情况,也就是hea.原创 2021-03-24 01:52:16 · 114 阅读 · 0 评论 -
725. 分隔链表
挺复杂的一道链表题,但是也是慢慢磨出来了。先计算链表长度,看看每k个可以分配几个结点。不能只考虑不够的情况,还要考虑多的情况用yu=len%k算出有哪几个是多一个的这段代码特别关键,如果这一个链表需要多一个,而且num>0的话就往后走一格,因为如果只要0个的话,其实也就是要1个或者0个,而要一个的操作我们在下面就会实现if(yu-- > 0 && num > 0) head = head->next;/** * Definition for sin..原创 2021-03-20 02:07:42 · 83 阅读 · 0 评论 -
445. 两数相加 II
两种方法,第一种先反转两条链表然后相加然后再反转第二种用stack来存,然后对弹出的结点相加即可。最重要的是要让new出来的结点指向前一个结点,而不是前一个结点指向new出来的结点。然后更新前一个结点/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }.原创 2021-03-20 01:59:47 · 77 阅读 · 0 评论 -
24. 两两交换链表中的节点
写了两个递归,迭代太晚了写不出了,明天补上/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *nex.原创 2021-03-19 01:21:30 · 70 阅读 · 0 评论 -
83. 删除排序链表中的重复元素
简单的链表题,来一个记录前驱的指针pre和往前走的cur就行了,如果pre==cur,就让cur一直往前走,直到不相等,就让pre->next=cur。cur为空就退出/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int .原创 2021-03-19 01:18:33 · 72 阅读 · 0 评论 -
25. K 个一组翻转链表
迭代肯定是O(1)时复,但是我写不出,只能写出递归的也不知道符不符合要求。先判断当前剩余的链表长度是否小于k,如果小于就不进行反转,直接返回。否则就是熟悉的翻转链表的方法,翻转k次,0循环到k控制即可,此时head就是这组新链表的结尾,cur就是下一组新链表的头,我们递归改变下一组,将head->next改为reverseGroup(cur,k)的结果,然后返回当前链表的头结点,pre/** * Definition for singly-linked list. * struct Li..原创 2021-03-04 01:44:12 · 86 阅读 · 1 评论 -
328. 奇偶链表
不错的题。来两个结点分别走自己的路,分别形成奇偶两条链表。注意注意要记录偶数链表的头结点,然后让奇的尾连上偶的头。循环结束的条件就是偶数走到头了,因为偶数是比较后面的那个,所以它一定先走到头。循环内部要做的事有四个奇数结点->next指向下一个奇数结点(也就是当前偶数结点的下一个)更新奇数结点偶数结点->next指向下一个偶数结点(也就是当前更新过后的奇数结点的下一个)更新偶数结点/** * Definition for singly-linked list. * struc.原创 2021-02-16 01:39:47 · 118 阅读 · 2 评论 -
237. 删除链表中的节点
这道题太强了!!我杀我自己,将node->val改成next->val,然后将自己的next指向next的next。就是将自己变成next,然后杀掉next,绝了/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class So.原创 2021-02-14 01:43:30 · 71 阅读 · 0 评论 -
138. 复制带随机指针的链表
哈希,绝对不是一个最好的办法,插个眼,和剑指offer的一样,再重新做一遍/*// Definition for a Node.class Node {public: int val; Node* next; Node* random; Node(int _val) { val = _val; next = NULL; random = NULL; }};*/class Solution {.原创 2021-02-08 01:36:36 · 100 阅读 · 0 评论 -
141. 环形链表
要记住这样的写法,如果head为空或者单结点,直接false。如果不是就把慢指针设为head,快指针设为head->next,防止一开始直接相等。while结束的条件就是他俩相等,内部先判断快指针是否为null或者快指针的下一个是否为null,这很重要,很容易出错,这里只要判断快的,因为五环的话快的一定先走完。最后返回true/** * Definition for singly-linked list. * struct ListNode { * int val; * L.原创 2021-01-28 01:01:11 · 99 阅读 · 0 评论 -
23. 合并K个升序链表
1.暴力法:遍历每一条链表,将每个结点加入vector,然后对vector进行sort,cmp的用法是如果返回值为1就不交换。最后遍历链表,创建新链表即可,重点是将最后tmp的next设为空指针!!必须必须,链表结尾必须为空2.分治法:归并排序,写一个切分函数,再写一个merge函数,因为数组中存的是链表的头,而每一条链表又是有序的,所以当我们切分到一个结点时,就当做切分完毕,只剩一条链表就是有序的(和只剩一个元素就算是有序的右异曲同工之妙)。left和right相等时就是切分完毕,返回lists[l..原创 2021-01-19 01:51:21 · 146 阅读 · 0 评论 -
21. 合并两个有序链表
新建一个h结点作为新链表的头(哨兵结点),要new不要初始化为nullptr,来一个cur来在链表上移动。遍历两条链表,只要一条空就结束遍历,用cur的next指向未空的另一条链表即可。将比较小的那个结点直接拷贝构造,是深拷贝等于新建一个结点,而不是指向l1,不然会改变l1的指向。并将cur指向next,l1也往后走一步。l2同理。最后返回哨兵的next/** * Definition for singly-linked list. * struct ListNode { * int v..原创 2021-01-18 01:56:21 · 99 阅读 · 0 评论 -
19. 删除链表的倒数第N个节点
链表=双指针=空间鲁棒性快指针先走n步,当快指针走到null时,慢指针指向倒数第n个。因为遍历一遍,所以用一个int变量记录快指针走了几步,当快指针走的步数大于等于n时,才让慢指针开始走。因为要删除,所以要来一个pre指针记录当前指针的前驱指针,删除操作就是直接让pre指向当前指针的next即可。最后判断,如果快指针在走n步直接走到结尾了,那么证明要删除头结点,直接返回head->next即可,通过判断pre是否为空来看是否是删除头。否则就删除slow指针指向的结点,最后返回head/** *.原创 2021-01-18 01:33:58 · 116 阅读 · 0 评论 -
2. 两数相加
简直裂开,代码很乱。同时遍历两个链表,两个都遍历完才算结束,取两个链表当前结点的值,判断是否为空,如果不为空就是val,如果为空就是0,用(a+b+carry)%10初始化tmp结点,tmp用来作为next,carry初始为0,因为这一轮的carry在下一轮才能用,所以计算carry是在计算a+b后面的,carry = (a+b)/10,将cur的next指向tmp,cur=cur->next,如果不为空的话就让l1和l2往后走。最后可能还会有一个进位所以退出循环后要判断carry是否为1,如果..原创 2021-01-14 01:35:18 · 80 阅读 · 0 评论 -
234. 回文链表
法一:遍历一遍链表,存到vector,然后反转和之前的判断法二:快慢指针找到中点,反转后半部分链表,然后一个从起点一个从中点走即可/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public: .原创 2021-01-11 00:43:30 · 79 阅读 · 0 评论 -
206. 反转链表
迭代好写多了,3个指针即可,最后当cur走到空时,pre就是新链表的头/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public: ListNode* reverseList(ListNode*.原创 2021-01-10 02:00:10 · 81 阅读 · 0 评论 -
160. 相交链表
两个方法,难的是第一个。/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public: ListNode *getIntersectionNode(ListNode *headA, ListNod.原创 2021-01-09 02:03:24 · 84 阅读 · 0 评论 -
148. 排序链表(归并排序)
用归并排序给链表排序快慢指针,慢一步快两步,快到终点了,慢也到终点或者中点的左边了。设置一个tmp为切分点(slow)下一个,将slow的next设为空,相当于把链表一分为二。左链表等于递归排序左边,将head传进去即可,右链表递归右边传入tmp。定义一个h为当前链表头=cur,cur一直往前,左小于等于右,就插入左到cur后面,反之右。最后结束后一定有一边没遍历完,将整条链表插在cur后面,cur指向非空的头即可。最后返回h->next/** * Definition for singl..原创 2021-01-09 01:59:33 · 243 阅读 · 1 评论 -
142. 环形链表 II
fast走两步,所以要判断自身和next是否为空。/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public: ListNode *detectCycle(ListNode *head) { .原创 2021-01-08 01:56:21 · 96 阅读 · 0 评论 -
146. LRU 缓存机制
class LRUCache {public: //O(1)时间复杂度取值肯定要用到容器,因为没有这么diao的算法 //map来存键值对,用一个堆来存这个map,对其进行get之后对其进行上浮操作? LRUCache(int capacity) { _capacity = capacity; } int get(int key) { //用过之后把它放到队列尾部 for(vector<pair<原创 2021-01-08 01:52:34 · 99 阅读 · 0 评论 -
剑指offer——删除链表中重复的结点C++
因为是有序链表,所以依次和后一个比较即可。三个指针,一个作为pHead的前驱,用来最后返回整条链表。一个是工作结点,一直往后。一个是pre结点,指向确定不是重复的结点。如果下一个结点不为空(必须写)且当前值和下一个结点值相等,就进入循环,一直找到第一个和下一个结点不等的结点,但是此时的cur还是那个重复结点,所以cur要指向下一个,并将pre指向cur。但是现在这一个不能保证它是不重复的,所以再次进入循环。如果当前和下一个不等了,就将pre和cur都往后移一格。/*struct ListNode .原创 2021-01-05 02:32:10 · 184 阅读 · 1 评论 -
剑指offer——链表中环的入口结点C++
链表=空间鲁棒性=双指针法一:map法二:双指针,先通过快慢指针判断是否有环。如果无就直接返回空,如果有,就将一个结点重新放回起点,另一个还在相遇点,让它俩速度一样,一次走一步,最后相遇的点的就是环的入口。链表头到环入口长度为–a环入口到相遇点长度为–b相遇点到环入口长度为–c则:相遇时快指针路程=a+(b+c)k+b ,k>=1 其中b+c为环的长度,k为绕环的圈数(k>=1,即最少一圈,不能是0圈,不然和慢指针走的一样长,矛盾)。慢指针路程=a+b快指针走的路程是慢指.原创 2021-01-05 02:23:35 · 188 阅读 · 0 评论 -
剑指offer——两个链表的第一个公共结点C++
链表题一定要想到快慢指针三种方法:1.用一个map记录第一条链表每个结点是否出现,遍历第二条时判断即可。2.我称之为相亲相爱法,因为两条链表的长度不确定,所以让两个指针分别走1+2两条链表的长度就可以了,这样走的就是相等了。两个结点相等时退出循环(这样就算两个结点都指向空结点也不会死循环)。当1为空,就让1指向链表2的头,2为空,就让2指向链表1的头。3.算出两条链表的长度len1和len2,假设len1>len2,就让链表1的指针先走len1-len2步,然后再一起走就行了/*stru.原创 2020-12-30 01:59:26 · 180 阅读 · 0 评论 -
剑指offer——二叉搜索树与双向链表C++
树的递归操作说来说去就这么几个,这里很明显要用中序,因为要形成的是从小到大的双向链表。BST的中序就是从小到大的。这里的中序就难在根那个地方的操作。递归函数需要一个指针的引用来作为前一个结点(pre),pre的初值为空指针。递归函数先进行左子树的递归,递归到最左的结点后,将其left改为pre(这样你就知道pre的初值为什么是空指针了,因为最左的结点的left是不可能有数字的)。如果pre不为空,就将pre的right改为当前结点。将pre改为root。我们可以想象pre是指向你自己构建的链表的最后一个.原创 2020-12-27 02:06:27 · 218 阅读 · 0 评论 -
剑指offer——复杂链表的复制C++
默认所有结点的random指针不会指向不在链表中的独立结点。两种方法:递归和循环递归:需要通过一个辅助的map来实现,这个map是用来处理random指针指向的结点的,防止重复新建node。在递归函数中根据当前结点的值new一个结点指针,在map记录当前指针对应的指针是新建的这个。然后递归next结点。当next都递归完后,判断当前结点的random是否为空,如果不为空,就将新建的这个结点的random指向map存储的原结点的random指针的拷贝指针。最后返回新建的指针即可。循环:三步法,每一步都.原创 2020-12-27 01:57:32 · 180 阅读 · 0 评论 -
剑指offer——合并两个排序的链表C++
链表=指针=保证鲁棒性=检查空指针这里用了两种方法:分别是递归和循环递归:因为两条链表分别都是有序的,所以当一条链表的头结点为空指针时,返回另一条链表头结点即可,两条都空也没事,也就是返回一个空指针。接下来两个指针都不是空指针,定义一个指针,将当前两条链表的头结点值较小的那个赋值给这个指针。这个指针的next递归调用该函数,参数值那里改一下就行,将头结点赋给cur的往后移一位。最后返回cur即可。循环:开头的检查是一样的,一条链表的头结点为空指针时,返回另一条链表头结点。定义一个mergeNode为.原创 2020-12-25 02:08:05 · 232 阅读 · 0 评论 -
剑指offer——反转链表C++
有链表就有指针操作,有指针操作就要防卫式编程,保证代码鲁棒性是最重要的。对NULL做操作是会崩溃的,就和今晚的我一样,很简单的题却做不出这道题最好画图思考一下操作,其实就是经过一轮循环,把每个指针的next指向前一个结点。但是我们要考虑到,如果把next指向前一个结点,那么原本的next结点就找不到了,所以我们要在赋值之前保存next结点。又因为我们我们要指向前一个结点,所以要定义一个指针指向前一个结点。最后我们用三个指针进行操作。1.保存next。2.将next指向前一个结点。3.前一个结点指向当前.原创 2020-12-25 01:46:25 · 130 阅读 · 0 评论 -
剑指offer——链表中倒数第k个结点
法一:遍历两次,第一次数出有几个结点,第二次遍历到n-k时return。结果:回家等通知法二:类似一把尺子,可以叫他前后指针(快慢指针不准确),先让一个指针走k-1步,然后另一个指针指向头结点0。当快指针走到尾结点时,慢指针刚好走到n-k的位置。因为快慢指针差的距离刚好是k-1。假设结点有n个,那么最后一个结点的位置是n-1,减去k-1刚好是n-k。但是还是拿不到offer,因为你完全没有考虑鲁棒性还有三点必须进行判断1.头结点是否为空结点,如果为空,那么我们会试图访问空指针的内存2.结点总.原创 2020-12-24 02:20:01 · 317 阅读 · 0 评论 -
剑指offer——从尾到头打印链表
链表题再做不出,枉费我白刷这么久PAT,遍历链表加入数组然后reverse即可。/*** struct ListNode {* int val;* struct ListNode *next;* ListNode(int x) :* val(x), next(NULL) {* }* };*/class Solution {public: vector<int> printList.原创 2020-12-23 01:58:38 · 160 阅读 · 0 评论 -
19年冬季第二题 PAT甲级 1165 Block Reversing (25分)
Given a singly linked list L. Let us consider every K nodes as a block (if there are less than K nodes at the end of the list, the rest of the nodes are still considered as a block). Your job is to reverse all the blocks in L. For example, given L as 1→2→3原创 2020-12-02 01:28:57 · 225 阅读 · 0 评论 -
2019年9月8日秋季PAT甲级题解-2-1161-Merging Linked Lists (25 分)
Given two singly linked lists L1=a1→a2→⋯→an−1→an and L2=b1→b2→⋯→bm−1→bm. If n≥2m, you are supposed to reverse and merge the shorter one into the longer one to obtain a list like a1→a2→bm→a3→a4→bm−1⋯. For exam原创 2020-11-29 02:17:02 · 290 阅读 · 0 评论 -
1133 Splitting A Linked List (25分)
Given a singly linked list, you are supposed to rearrange its elements so that all the negative values appear before all of the non-negatives, and all the values in [0, K] appear before all those greater than K. The order of the elements inside each class原创 2020-11-13 00:05:42 · 167 阅读 · 0 评论 -
1097 Deduplication on a Linked List (25分)
Given a singly linked list L with integer keys, you are supposed to remove the nodes with duplicated absolute values of the keys. That is, for each value K, only the first node of which the value or absolute value of its key equals K will be kept. At the m原创 2020-11-05 01:22:06 · 101 阅读 · 0 评论 -
1074 Reversing Linked List (25分)
Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given L being 1→2→3→4→5→6, if K=3, then you must output 3→2→1→6→5→4; if K=4, you must output 4→3→2→1→5→6.Input Specification:Each原创 2020-10-30 01:49:52 · 62 阅读 · 0 评论 -
1052 Linked List Sorting (25分)
A linked list consists of a series of structures, which are not necessarily adjacent in memory. We assume that each structure contains an integer key and a Next pointer to the next structure. Now given a linked list, you are supposed to sort the structures原创 2020-10-23 01:38:59 · 79 阅读 · 0 评论 -
1032 Sharing (25分)
#include<iostream>#include<cstdio>using namespace std;struct node{ char c; int next; bool flag; node(char _c, int _next, bool _flag):c(_c),next(_next),flag(_flag){}}nodes[100001];int main(){ int s1, s2, n; cin>&g原创 2020-10-17 00:45:20 · 80 阅读 · 0 评论