LeetCode-链表-反转链表+链表的中间结点
LeetCode-链表-反转链表+链表的中间结点
✏️ 关于专栏:专栏用于记录
prepare for the coding test
。
文章目录
- LeetCode-链表-反转链表+链表的中间结点
- 📝 反转链表
- 🎯题目描述
- 🔍 输入输出示例
- 🧩题目提示
- 🧪AC
- 📝 链表的中间结点
- 🎯题目描述
- 🔍 输入输出示例
- 🧩题目提示
- 🧪AC
- 🌟 总结
- ✅ 反转链表
- ✅ 链表的中间结点
📝 反转链表
🎯题目描述
给你单链表的头节点
head
,请你反转链表,并返回反转后的链表。
🔗题目链接:反转链表
🔍 输入输出示例
示例 1:

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
示例 2:

输入:head = [1,2]
输出:[2,1]
示例 3:
输入:head = []
输出:[]
🧩题目提示
- 链表中节点的数目范围是
[0, 5000]
-5000 <= Node.val <= 5000
🧪AC
简单理解:比如链表为 1→2→3。创建一个新的空链表,然后用头插法依次把节点 1,2,3 插到这个新链表的头部,就得到了链表 3→2→1,这正是反转后的链表。


/*** 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 *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* reverseList(ListNode* head) {ListNode* pre = nullptr;ListNode* cur = head;while(cur){ListNode* nnxt = cur->next;cur->next = pre;pre = cur;cur = nnxt;}return pre;}
};
📝 链表的中间结点
🎯题目描述
给你单链表的头结点
head
,请你找出并返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。
🔗题目链接:链表的中间结点
🔍 输入输出示例
示例 1:

输入:head = [1,2,3,4,5]
输出:[3,4,5]
解释:链表只有一个中间结点,值为 3 。
示例 2:

输入:head = [1,2,3,4,5,6]
输出:[4,5,6]
解释:该链表有两个中间结点,值分别为 3 和 4 ,返回第二个结点。
🧩题目提示
- 链表的结点数范围是
[1, 100]
1 <= Node.val <= 100
🧪AC
可以利用「快慢指针」技巧来找到链表的中间节点。具体做法是定义两个指针:fast
和 slow
,其中 fast
每轮移动两步,slow
每轮移动一步。由于 fast
的移动速度始终是 slow
的两倍,当 fast
遍历完整个链表时,slow
恰好位于中间位置。
根据链表长度的不同,需区分以下两种情况:
- 链表长度为奇数:当
fast
指向最后一个节点时,slow
正好指向链表的中间节点。 - 链表长度为偶数:当
fast
越过尾节点(即指向null
)时,slow
此时指向的是两个中间节点中的第二个。
因此,我们可以在 fast
到达尾节点或越界时结束循环,并返回 slow
所指的位置作为中间节点。

/*** 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 *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* middleNode(ListNode* head) {ListNode* fast = head;ListNode* slow = head;while(fast&&fast->next){fast = fast->next->next;slow = slow->next;}return slow;}
};
🌟 总结
✅ 反转链表
- 运用 迭代法,通过
cur
遍历原链表,利用一个pre
指针记录反转后的链表头。 - 关键在于每次保存
cur->next
,以防链表断裂,然后逐步“头插”到新的链表中。 - 该方法时间复杂度为 O(n),空间复杂度为 O(1),高效稳定。
✅ 链表的中间结点
- 使用 快慢指针法(Two Pointers) 快速定位中间结点。
fast
每次走两步,slow
每次走一步,fast
走完时,slow
恰好在中点。- 可统一处理奇偶长度链表:当
fast
为nullptr
或fast->next == nullptr
时停止,返回slow
即可。
使用 快慢指针法(Two Pointers) 快速定位中间结点。
fast
每次走两步,slow
每次走一步,fast
走完时,slow
恰好在中点。- 可统一处理奇偶长度链表:当
fast
为nullptr
或fast->next == nullptr
时停止,返回slow
即可。
将两者结合又将产生什么样的火花呢?参加LeetCode-234回文链表,下篇博客我们将一起探究这道题~