一、题目
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例 1:
更多细节请参看官方题目详情。
二、题解
2.1 迭代法
| 1 --> | 2--> | 3 --> | 4--> | 5 | |||
|---|---|---|---|---|---|---|---|
| head | |||||||
| head->next |
对于一个链表,已知头节点,我们只知道头节点和头节点的下一个节点。
现在要实现链表的反转, 我们可以先创建一个链表 ListNode *pre = nullptr;,然后不断遍历当前链表的节点,使其指向 pre
| 1 --> | 2--> | 3 --> | 4--> | 5--> | nullptr | ||
|---|---|---|---|---|---|---|---|
| head | head->next | ||||||
| ListNode *pre = nullptr | <-- cur | ||||||
| <-- (cur->next) |
链表反转通常需要用到三个指针:
- 当前节点指针 cur,需要连接前一个节点,原来的首节点应该连接 nullptr 节点
- 前驱节点指针 pre,上一步连接完成,应该让pre指针指向cur
- 后继节点指针 在上两个步骤开始之前应该最先记录当前节点的后继节点,便于找到更新前的cur-->next
在反转链表的过程中,当前节点指针指向的节点的 next 指针需要指向其前驱节点,因此需要在遍历链表的同时记录当前节点指针和前驱节点指针。由于链表是单向的,需要用到后继节点指针来记录下一个要遍历的节点。
/**
* 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 != nullptr)
{
ListNode* after = cur->next;
cur->next = pre;
pre = cur;
cur = after;
}
return pre;
}
};
2.2 递归法
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
}
};
三、总结
| 题目 | 知识点 | 进度 |
|---|---|---|
| 136 | 数组、位运算(异或)、哈希表 | 1 |
| 121 | 数组、动态规划 | 2 |
| 3 | 字符串、滑动窗口、哈希表 | 3 |
| 131 | 字符串、回溯、动态规划 | 4 |
| 438 | 字符串、滑动窗口、哈希表 | 5 |
| 206 | 递归、链表 | 6 |