25 K个一组反转链表
解题思路:
大致过程可以分解为
1、找到待翻转的k个节点(注意:若剩余数量小于 k 的话,则不需要反转,因此直接返回待翻转部分的头结点即可)。
2、对其进行翻转。并返回翻转后的头结点(注意:翻转为左闭又开区间,所以本轮操作的尾结点其实就是下一轮操作的头结点)。
3、对下一轮 k 个节点也进行翻转操作。
4、将上一轮翻转后的尾结点指向下一轮翻转后的头节点,即将每一轮翻转的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:
ListNode *reverselist(ListNode *head,ListNode *tail){
ListNode *pre=nullptr;
while(head!=tail){
ListNode *next=head->next;
head->next=pre;
pre=head;
head=next;
}
return pre;
}
ListNode* reverseKGroup(ListNode* head, int k) {
if(head==nullptr||head->next==nullptr) return head;
ListNode *tail=head;
for(int i=0;i<k;i++){
if(tail==nullptr){
return head;
}
tail=tail->next;
}
ListNode *newhead=reverselist(head,tail);
head->next=reverseKGroup(tail,k);
return newhead;
}
};
解法2:迭代
每隔k个找到最开始的结点,和最后的结点,并且记录下一个要反转的头节点,将上一个的为节点指向下一个头节点;对于每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:
ListNode *reverse(ListNode *head){
if(head==nullptr||head->next==nullptr) return head;
ListNode *next=head->next;
ListNode *newhead=reverse(next);
next->next=head;
head->next=nullptr;
return newhead;
}
ListNode* reverseKGroup(ListNode* head, int k) {
if(head==nullptr||head->next==nullptr) return head;
//定义虚拟头节点,并将下一节点指向head;
ListNode *dummpy = new ListNode(0,head);
//初始化pre和end,pre指每次要反转的链表头节点的上一个节点
//end指每次要反转的链表的尾部节点;
ListNode *pre=dummpy;
ListNode *end=dummpy;
while(end->next!=nullptr){
//循环K次找到需要反转的链表的结尾,这里每次循环要判断end是否为空,
for(int i=0;i<k&&end!=nullptr;i++){
end=end->next;
}
//如果end==nullptr,则不需要反转
if(end==nullptr) break;
//先记录end->next,即为下次反转的开始头节点
ListNode *next=end->next;
//断开链表
end->next=nullptr;
//记录反转的头节点;
ListNode *start=pre->next;
//反转链表;
pre->next=reverse(start);
start->next=next;
pre=start;
end=start;
}
return dummpy->next;
}
};