05 反转链表
1 反转链表



1.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 != nullptr) {
ListNode* nxt = cur->next;
cur->next = pre;
pre = cur;
cur = nxt;
}
return pre;
}
};
- 递归做法
点击查看代码
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (head == nullptr || head->next == nullptr) {
return head;
}
auto new_head = reverseList(head->next);
head->next->next = head;
head->next = nullptr;
return new_head;
// 1->2->3->4->5
// new_head 返回 5
// 此时head = 4 5->4->nullptr
// new_head 依旧是 5
// 此时 head = 3 5->4->3->nullptr
}
};
- 时间复杂度:$$O(n)$$
- 空间复杂度:$$O(n)$$
递归的做法还是不太好想。
2 反转链表 II


2.1 代码实现
点击查看代码
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int left, int right) {
ListNode* dummyHead = new ListNode(0, head);
// 需要找到需要反转的头结点的previous
ListNode* p0 = dummyHead;
for (int i = 0; i < left - 1; ++i) {
p0 = p0->next;
}
ListNode* pre = nullptr;
ListNode* cur = p0->next;
for (int i = 0; i < right - left + 1; ++i) {
ListNode* nxt = cur->next;
cur->next = pre;
pre = cur;
cur = nxt;
}
// cur指向5,pre指向4
p0->next->next = cur;
p0->next = pre;
return dummyHead->next;
}
};
为什么需要new一个虚拟的头结点,这是因为如果left == 1不太好处理。
3 K个一组翻转链表



3.1 解题思路
由于剩下不足k个元素时是不能翻转的,所以我们可以先求出链表的长度。
翻转之前,先判断一下剩余节点的个数。
3.2 代码实现
点击查看代码
/**
* 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* reverseKGroup(ListNode* head, int k) {
ListNode* cur = head;
int cnt = 0;
// 1. 求出链表的总长度
while (cur != nullptr) {
cnt += 1;
cur = cur->next;
}
// 2. 判断剩余要翻转的元素个数是否大于 k 个
ListNode* dummy_head = new ListNode(0, head);
ListNode* p0 = dummy_head;
ListNode* pre = nullptr;
while (cnt >= k) {
cnt -= k;
// 翻转k个元素
pre = nullptr;
cur = p0->next;
for (int i = 0; i < k; ++i) {
ListNode* nxt = cur->next;
cur->next = pre;
pre = cur;
cur = nxt;
}
ListNode* temp = p0->next; // new p0
p0->next->next = cur;
p0->next = pre;
p0 = temp;
}
return dummy_head->next;
}
};
- 时间复杂度:$$O(n)$$
- 空间复杂度:$$O(1)$$

浙公网安备 33010602011771号