题目链接
题目:
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例:
给你这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
说明:
你的算法只能使用常数的额外空间。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
分析:
这题内容看着确实简单,但细想起来却有很多麻烦的地方——需要判断的边界条件/特殊条件太多了,比方说初始元素的个数;指针又该如何放;for循环到哪个边界,边界的节点如何翻转处理。
大概解决方法分成了下面几点:
1、设置含头尾指针参数的翻转函数,用于k个结点链表翻转
2、开辟一个ListNode对象,保证for循环可从0开始
3、k个结点链表的翻转函数可以通过头结点连接指点的next来保证for循环不用考虑边界条件。
4、k个结点翻转函数可以返回头指针与尾指针,方便循环中连接k个一组的各个链表
代码:
class Solution {
public:
pair<ListNode*,ListNode*> reverseList(ListNode* start, ListNode* end) {
ListNode* prev = end->next;
ListNode* p = start;
while (prev != end) {
ListNode* next = p->next;
p->next = prev;
prev = p;
p = next;
}
return{ end,start };
}
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode* ret = new ListNode(0);
ret->next = head;
ListNode* pre = ret;
while (head) {
ListNode* end = pre;
for (int i = 0; i < k; i++) {
end = end->next;
if (!end) {
return ret->next;
}
}
ListNode* nex = end->next;
tie(head, end) = reverseList(head, end);
pre->next = head;
end->next = nex;
pre = end;
head = end->next;
}
return ret->next;
}
};