自己写出来的第一道hard,菜鸡落泪,写了将近两个小时,过程全靠自己画图
具体思路
1.分组,找到每一组的开头和结尾
2.按组遍历,将头尾的两组作为边界条件,最后再处理,先看中间组需要如何处理
3.对中间组的处理如下
①需要将上一组的第一个的next设为该组的最后一个节点,即将新链表的上一组的最后一个节点和这组的第一个节点建立联系
②该组的新末尾指向下一组的新开头节点
③该组内指针反向
我的代码
/**
* 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* reverseKGroup(ListNode* head, int k){
int p=k;
//flag判断是否最后一组节点小于k
bool flag=false;
//ishead判断是否是第一组节点
bool ishead=true;
//bool wait=true;
//newHead新链表头节点
ListNode *newHead=NULL,*nowNode=head;
//first,last记录当前组第一个和最后一个节点
//prefirst记录上一组第一个节点
ListNode *first=head,*last=NULL,*prefirst=NULL;
//记录前一个节点
ListNode *preNode=NULL;
while(nowNode!=NULL){
//每一组第一个节点先指向空结点
preNode=NULL;
for(int i=1;i<=k;i++){
//记录每组第一个节点和最后一个节点
if(i==1)first=nowNode;
if(i==k)last=nowNode;
if(nowNode==NULL){
flag=true;
break;
}
//记录后一个结点
ListNode *nextNode=nowNode->next;
nowNode->next=preNode;
//两个指针都想后移
preNode=nowNode;
nowNode=nextNode;
}
if(flag){
//最后一组节点小于k
//将翻转后的最后一组节点再转回来
prefirst->next=first;
nowNode=preNode;
preNode=NULL;
while(nowNode!=NULL){
ListNode *nextNode=nowNode->next;
nowNode->next=preNode;
preNode=nowNode;
nowNode=nextNode;
}
break;
}
if(ishead){
newHead=last;
ishead=false;
}else{
//连接上一组第一个节点和这一组最后一个节点
prefirst->next=preNode;
}
prefirst=first;
}
return newHead;
}
};
大佬的代码