有一个单链表,请设计一个算法,使得每K个节点之间逆序,如果最后不够K个节点一组,则不调整最后几个节点。例如链表1->2->3->4->5->6->7->8->null,K=3这个例子。调整后为,3->2->1->6->5->4->7->8->null。因为K==3,所以每三个节点之间逆序,但其中的7,8不调整,因为只有两个节点不够一组。
给定一个单链表的头指针head,同时给定K值,返回逆序后的链表的头指针。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
class KInverse {
public:
//这是我有一篇博客中描述的单链表逆序的函数 照搬过来的
ListNode* reverse(ListNode* head){
if(head==NULL){
return NULL;
}
auto cur=head;
ListNode* pre=NULL;
while(cur!=NULL){
auto pnext=cur->next;
cur->next=pre;
pre=cur;
cur=pnext;
}
return pre;
}
ListNode* inverse(ListNode* head, int k) {
// write code here
if(head==NULL){
return NULL;
}
int i=1; //注意i是从1开始,结束时p指针指向NULL,i最后的值要比结点数多1。
ListNode* p=head; //p是遍历指针
ListNode* pre=head; //pre记录每次做逆序的起始点
ListNode* phead=NULL; //逆序后的头结点
ListNode* pend=NULL; //每次逆序k长度结点后,逆序完的那个尾结点。
//如果一个链表为1->2->3->4,那么pend逆序完指向1,phead指向3。
while(p!=NULL){
if(i%k==0){ // i刚好是k的倍数
auto q=p->next;
p->next=NULL; // 这个很容易遗漏 如果1->2->3>4 p指针刚好走到3 要将3->next=NULL 否则一直逆序到底
if(phead==NULL){
phead=reverse(pre);
}
else{
pend->next=reverse(pre);
}
pend=pre;
pre=q;
p=pre;
}
else{
p=p->next;
}
i++;
}
if(i-1<k){ // i减1在前面说明
return head;
}
if((i-1)%k>0){
pend->next=pre; // i最后除以k有余数 表明还有个数小于k几个结点 不能逆序 我们直接将pend连接到这几个结点的头结点
}
return phead;
}
};