给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序。
示例 :
给定这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
说明 :
- 你的算法只能使用常数的额外空间。
- 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
//=======================================================================
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseKGroup(struct ListNode* head, int k) {
//处理特殊条件
if(head == NULL || head->next == NULL || k<=1)
{
return head;
}
//先找到第一组,包含k个元素,newHead指向第一组后面的第一个结点
struct ListNode *newHead = head;
int count=0;
while(newHead && count < k)
{
newHead = newHead->next;
count += 1;
}
// 1, 2, 3, 4, 5 k=2
// head newHead newHead
// temp
// ---------------->
// newHead
// head
// temp
//
//如果第一组可以找全,则进行翻转; 反之,不需要翻转
if(count == k)
{
//同理,处理后续元素的k组翻转,最后返回翻转后的头结点newHead
newHead = reverseKGroup(newHead, k);
//对前面k个元素进行翻转
struct ListNode *temp=NULL;
while(count > 0)
{
temp = head->next; //备份第二个结点
head->next = newHead; //两组衔接过渡 ,第一个的下一个结点为下一组翻转后的头结点
newHead = head; //此时的第一个为合并数据后的部分的第一个
head = temp; //第二个为新的头
count -= 1;
}
head = newHead;
}
return head;
}
//=======================================================================
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *reverseList(struct ListNode *head, int k)
{
struct ListNode *pnext=head;
while(pnext && k>0) //找到k个元素的下一个元素
{
pnext=pnext->next;
k--;
}
if(k>0) //不到k个元素,则无需翻转
return head;
struct ListNode *nexthead=pnext, *pcur=head, *temp=NULL;
while(pcur != pnext) //前面k个元素以此翻转
{
temp=pcur->next;
pcur->next = nexthead;
nexthead=pcur;
pcur=temp;
}
return nexthead;
}
struct ListNode* reverseKGroup(struct ListNode* head, int k) {
if(head==NULL || head->next==NULL || k<=1)
{
return head;
}
struct ListNode dummy={.next=head}; //设置dummy首结点
struct ListNode *pcur=&dummy;
while(pcur) //从前往后以此翻转k个元素
{
pcur->next = reverseList(pcur->next, k); //翻转前k个元素
for(int i=0; pcur && i<k; ++i) //前进k个元素
{
pcur=pcur->next;
}
}
return dummy.next;
}