反转链表,技巧也是dummy节点、双指针
206. 反转链表(简单)
92. 反转链表II(中等)
25. K个一组翻转链表(困难)
234. 回文链表(简单)
完全反转链表,记住这个,这是所有反转链表的基础
/**
* 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 *next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
return pre;
}
};
部分反转链表,在反转链表的基础上增加了找左右边界,以及边界截断与连接
/**
* 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 *next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
return pre;
}
ListNode* reverseBetween(ListNode* head, int left, int right) {
ListNode dummy;
dummy.next = head;
//找出左右边界
ListNode *pre = &dummy;
for (int i = 0; i < left-1; i++) {
pre = pre->next;
if (pre == nullptr) return head;
}
ListNode *leftNode = pre->next;
ListNode *rightNode = pre;
for (int i = 0; i < right - left + 1; i++) {
rightNode = rightNode->next;
if (rightNode == nullptr) break;
}
//保存左右外边界
ListNode *cur = rightNode->next;
//截断
pre->next = nullptr;
rightNode->next = nullptr;
//翻转
reverselist(leftNode);
//连接
pre->next = rightNode;
leftNode->next = cur;
return dummy.next;
}
};
k个一组翻转链表,跟上面的一样,增加边界处理
/**
* 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:
void reverselist(ListNode *head)
{
ListNode *pre = nullptr;
ListNode *cur = head;
while (cur) {
ListNode *next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
}
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode dummy;
dummy.next = head;
ListNode *pre = &dummy;
while (pre) {
ListNode *left = pre->next;
ListNode *right = pre;
for (int i = 0; i < k; i++) {
right = right->next;
if (right == nullptr) return dummy.next;
}
//截断
ListNode *cur = right->next;
pre->next = nullptr;
right->next = nullptr;
//翻转
reverselist(left);
//接上
pre->next = right;
left->next = cur;
//下一个
pre = left;
}
return dummy.next;
}
};
234. 回文链表(简单)
只写进阶解法,额外增加了双指针找中点
/**
* 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* reverse(ListNode *head)
{
ListNode *pre = nullptr;
ListNode *cur = head;
while (cur) {
ListNode *next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
return pre;
}
bool isPalindrome(ListNode* head) {
//快慢指针找到中点
ListNode *s, *f;
s = f = head;
while (f && f->next) {
f = f->next->next;
s = s->next;
}
//奇数时,只反转后半段
if (f) s = s->next;
ListNode* right = reverse(s);
ListNode* left = head;
while (right) {
if (right->val != left->val) return false;
right = right->next;
left = left->next;
}
return true;
}
};