leetcode 25.k个一组翻转链表 hard
题目描述:
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例 :
给定这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
说明 :
你的算法只能使用常数的额外空间。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
解题思路:
解法1:
用递归来做(没什么难点,主要就是把特殊情况考虑全面。
解法2:
用循环来做,重点是这个reverseoneGroup的实现
递归代码:
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
if(!head || k==1)
return head;
int len=0;
ListNode *cur=head,*head_next=nullptr;
while(cur){
++len;
head_next= (len==(k+1)?cur:head_next);
cur=cur->next;
}
if(len<k)
return head;
cur=head;
ListNode *pre=nullptr,*after=nullptr;
for(int i=0;i<k;++i){
after=cur->next;
cur->next=pre;
pre=cur;
cur=after;
}
head->next=reverseKGroup(head_next,k);
return pre;
}
};
循环代码:
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
if(!head || k<=1)
return head;
ListNode dummy(0);
dummy.next=head;
ListNode *pre=&dummy,*cur=head;
for(int i=1;cur != nullptr;++i){
if(i%k==0){
pre=reverseoneGroup(pre,cur->next); // pre代表上一个group的最后一个节点,cur->next 表示下一个group的第一个节点
cur=pre->next;
}
else
cur=cur->next;
}
return dummy.next;
}
ListNode * reverseoneGroup(ListNode *last,ListNode *new_head){ //函数功能反转 [last+1,new_head-1] 这部分节点,返回反转后的尾节点。
ListNode *tail=last->next;
ListNode *cur=last->next,*pre=nullptr, *after=nullptr;
while(cur!=new_head){
after=cur->next;
cur->next=pre;
pre=cur;
cur=after;
}
last->next=pre;
tail->next=new_head;
return tail;
}
};