分析:这道题其实并不难,只是题目限制了很多空间,限制不能交换值,只能交换节点,限制了只能使用constant的空间,所以使用辅助栈的方式的做法不符合题意,当然用了也是可以Accept的,另当别论了。这道题其实类似于一道,不使用栈的单链表反转,只是这里是每k个节点反转一次。
代码如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
/*
Time Complexity:O(N)
Space Complexity:O(1)
*/
if(!head || k==1)return head;
ListNode *right=head,*left=head,*res=NULL,*tmp=NULL,*next=NULL,*last=NULL;
int i=0;
bool flag=false,first=false;
while(true){
i=0;
while(++i<k){
right=right->next;
//如果right为空,并且flag还没有置位,说明k比链表长度大,(ps:尼玛题意明明说了k is less than or equal to the length of link list
//,但是测试用例却提供了k大于length的情况)返回head,如果flag已经置位,说明不足k个节点,保持不动
if(!right)return flag?res:head;
}
//标记第一个right为返回节点,因为它是reverse之后的第一个结点
if(!flag){
res=right;
flag=true;
}
//first标志位表征是否将上一次k个节点的尾节点指向这一次的首节点,true表示要进行这一步操作,第一次不用
if(first)last->next=right;
first=true;
last=left;
//标记下一次开始的节点
next=right->next;
//链表反转
while(left!=right){
tmp=left->next;
left->next=right->next;
right->next=left;
left=tmp;
}
//如果next为空,说明没有节点了,直接返回
if(!next)return res;
right=next;
left=right;
}
}
};