1.问题描述
本题出自leetcode25 k个一组翻转链表,此题为困难题,给出一个链表,把整个链表的节点,k个为一组,翻转这一组的元素。
2.解决思路
首先得判断一共有多少个k个节点的组,然后遍历所有的组,把每个组分别翻转。那么需要考虑每一组翻转过后的第一个节点怎么跟上一组的最后一个节点连接,最后一个节点怎么跟下一组的第一个节点连接。首先需要定义一个虚拟节点,虚拟节点的作用就是缓冲一下遍历的速度,让虚拟节点能够跟上遍历的步伐。虚拟节点指向当前组的一个节点,这个节点指向下一组的节点,也就是一组的没翻转前的最后一个节点。反转部分就是普通的翻转。最后执行完后,把翻转部分和没翻转过的部分连接起来即可。
3.代码实现
ListNode* reverseKGroup(ListNode* head, int k) {
int len=0;//head链表的总长
ListNode *node=head;
ListNode *res=head;//返回值
while(node)//计算链表的总长
{
++len;
node=node->next;
}
int revergroup=len/k;//需要反转的组的数量
int num=k-1;
while(num--)//求出最后返回的节点
{
res=res->next;
}
ListNode *connnode=new ListNode(0);//虚拟节点
ListNode *reverlastnode;//
for(int i=0;i<revergroup;i++)
{
ListNode *prenode=nullptr;
reverlastnode=head;//每组反转后的最后一个节点
int tmpk=k;
while(tmpk)//反转部分
{
ListNode *nextnode=head->next;
head->next=prenode;
prenode=head;
head=nextnode;
--tmpk;
}
connnode->next=prenode;//前一组连接后一组
connnode=reverlastnode;//前一组的连接节点又成为下一组的连接点
}
if(reverlastnode)
reverlastnode->next=head;
return res;
}
4.总结
此题虽为困难题,但是主要思路还算是比较清晰,最重要的是注意细节,注意每个组之间的连接节点的关系,以及遍历的次数也是比较讲究,总之此题可以让我们对链表的遍历细节有更深刻的理解。