代码随想录刷题记录——链表
链表相关题目
2023-09-01
707.设计链表-leetcode 题目链接
题目:
关键点:
- 定义成员变量:
private: int _size; Node *_dummyHead;
- 定义链表节点结构体和构造函数:
//定义链表节点结构体 struct Node { int val; Node *next; Node(int val):val(val),next(nullptr) {} }; MyLinkedList() { //初始化链表 _dummyHead = new Node(-1);//虚拟头节点 _size = 0;//初始化链表长度为0,即[] }
- C++ AC code:
class MyLinkedList { public: //定义链表节点结构体 struct Node { int val; Node *next; Node(int val):val(val),next(nullptr) {} }; MyLinkedList() { //初始化链表 _dummyHead = new Node(-1);//虚拟头节点 _size = 0;//初始化链表长度为0,即[] } int get(int index) { if(index<0||index>_size-1) return -1; Node *cur = _dummyHead->next; while(index){ cur = cur->next; index--; } return cur->val; } void addAtHead(int val) { Node *temp = _dummyHead->next; Node *p = new Node(val); _dummyHead->next = p; p->next = temp; _size++; } void addAtTail(int val) { Node *p = new Node(val); Node *cur = _dummyHead; while(cur->next!=nullptr){ cur = cur->next; } cur->next = p; _size++; } void addAtIndex(int index, int val) { if(index>_size) return; Node *p = new Node(val); Node *cur = _dummyHead; while(index){ cur = cur->next; index--; } p->next = cur->next; cur->next = p; _size++; } void deleteAtIndex(int index) { if(index>_size-1||index<0) return; Node *cur = _dummyHead; while(index){ cur = cur->next; index--; } Node *temp = cur->next; cur->next = temp->next; delete temp; /* delete命令指示释放了tmp指针原本所指的那部分内存, 被delete后的指针tmp的值(地址)并非就是NULL,而是随机值。也就是被delete后, 如果不再加上一句tmp=nullptr,tmp会成为乱指的野指针 如果之后的程序不小心使用了tmp,会指向难以预想的内存空间 */ tmp=nullptr; _size--; } private: int _size; Node *_dummyHead; };
206. 反转链表-leetcode 题目链接
题目:给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
关键点:
- 双指针,pre,cur。初始条件:pre=null,cur=head;
- C++ AC code:
class Solution { public: ListNode* reverseList(ListNode* head) { ListNode *pre = nullptr, *cur = head, *temp; while(cur){ temp = cur->next; cur->next = pre; pre = cur; cur = temp; } return pre; } };
2023-09-03
24. 两两交换链表中的节点-leetcode 题目链接
题目:给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
知识点:
模拟,注意指针操作的先后顺序
虚拟头节点
C++ AC code:

class Solution { public: ListNode* swapPairs(ListNode* head) { ListNode *dummyHead = new ListNode(-1); dummyHead->next = head; ListNode *cur = dummyHead; while(cur->next){ if(cur->next->next){ ListNode *temp = cur->next;//dummyhead->1->2->3中指向1的指针 cur->next = cur->next->next; ListNode *q = cur->next->next;//dummyhead->1->2->3中指向3的指针 cur->next->next = temp; temp->next = q; cur = cur->next->next; } else{ cur = cur->next; } } return dummyHead->next; } };
19.删除链表的倒数第N个节点 题目链接
题目:给你一个链表,删除链表的倒数第 n
个结点,并且返回链表的头结点。
进阶:你能尝试使用一趟扫描实现吗?
知识点:
快慢指针,slow和fast,fast先走n步,当fast指向null时,slow距null长度为n,即slow指向的是倒数第n个节点
C++ AC code:

struct ListNode{ int val; ListNode *next; ListNode(int x): val(x), next(nullptr) {} }; class Solution { public: ListNode* removeNthFromEnd(ListNode* head, int n) { ListNode *dummyHead = new ListNode(-1); dummyHead->next = head; ListNode *slow = dummyHead, *fast = dummyHead; while(n+1){ fast = fast->next; n--; } while(fast){ fast = fast->next; slow = slow->next; } ListNode *temp = slow->next; slow->next = temp->next; delete temp; return dummyHead->next; } };
面试题 02.07. 链表相交 题目链接
题目:给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。
知识点:
将A、B链表右对齐,重叠部分一 一比较节点指针是否相同,是则返回该节点,遍历后未找到则返回null
C++ AC code:

#include<iostream> using namespace std; struct ListNode { int val; ListNode *next; ListNode(int x): val(x), next(nullptr) {} }; class Solution { public: ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { ListNode *curA = headA, *curB = headB; int lenA = 0, lenB = 0; while(curA){ lenA++; curA = curA->next; } while(curB){ lenB++; curB = curB->next; } //指针复位 curA = headA, curB = headB; int gap = lenA > lenB ? lenA-lenB : lenB - lenA; //这里默认链表A更长 if(lenA < lenB) swap(curA, curB); while(gap){ curA = curA->next; gap--; } while(curA){ if(curA == curB) return curA; curA = curA->next; curB = curB->next; } return nullptr; } };
142.环形链表II 题目链接
题目: 给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
说明:不允许修改给定的链表。
思路:
- 判断链表是否有环:快慢指针,快指针每次两步,当fast==slow时,证明有环。若有环,则相遇时slow指针肯定没走完第一圈,假设头结点就是环入口,则slow指针走完一圈时fast指针走完两圈,其他情况下fast指针走完两圈时slow指针还在第一圈,即此前已经相遇。
- 找到环的入口节点:
- 相遇时,slow指针步数:x+y,fast指针步数:x+y+n(y+z)
- 公式:2*(x+y)= x+y+n(y+z)==> x = (n-1)(y+z)+z,从公式中,可以看出,当p1从头结点走到环形入口节点时,p2也从相遇节点走到环形入口节点,即p1==p2时,p1或p2即为所求
C++ AC code:

class Solution { public: ListNode *detectCycle(ListNode *head) { ListNode *slow = head, *fast = head; while(fast&&fast->next){ slow = slow->next; fast = fast->next->next; if(fast == slow){//快慢指针在环内相遇 ListNode *p1 = head, *p2 = slow; while(p1!=p2){//x = (n-1)(y+z)+z,p1走x步后,将和p2在环入口相遇 p1 = p1->next; p2 = p2->next; } return p1;//环入口节点 } } return nullptr;//无环 } };
总结
- 链表主要种类:单链表,双链表,循环链表
- 链表存储方式:节点内存中分散存储,通过指针连在一起
- 链表增删改查
- 链表和数组对比:
- 必掌握知识点:链表结构体定义、双指针(链表反转)、虚拟头节点、快慢指针(判断有无环、删除倒数第n个节点)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏