使用上一题翻转区间内链表的思路
- 排除各类特殊情况:链表空,链表只有一个,一组节点数大于链表内节点总数
- 之后
- 第一组翻转需要特殊处理,因为它没有前结点
- 之后的所有组都按照:找反转头,反转头的前结点,反转尾,翻转尾的后节点,再按照部分翻转,之后链接翻转部分和原来部分即可
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*
* C语言声明定义全局变量请加上static,防止重复定义
*/
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @param k int整型
* @return ListNode类
*/
struct ListNode* reverseKGroup(struct ListNode* head, int k ) {
// write code here
//遍历获得链表节点个数
int list_count=0;
struct ListNode* count_head=head;
while(count_head){
count_head=count_head->next;
list_count++;
}
//如果空链表,或者链表只有一个元素,或者反转一组链表节点个数小于k,直接返回链表头
if(head==NULL || head->next ==NULL || list_count<k){
return head;
}
struct ListNode* node=head;
struct ListNode* org_head=head;
struct ListNode* org_head_pre=NULL;
int count=1;
while(count<=list_count){
if(count==k){
struct ListNode* org_tail=node;
struct ListNode* org_tail_next=node->next;
//原地反转法将需要反转的部分链表反转
struct ListNode* pre=org_tail_next;
struct ListNode* cur=org_head;
struct ListNode* next=cur->next;
while(cur!=org_tail_next){
cur->next=pre;
pre=cur;
cur=next;
next=next->next;
}
head=pre;//保存一下整个链表的头结点
}
if(count%k==0 && count>k){
//遍历寻找此次反转的头
int count_m=1;
struct ListNode* org_head=head;
while(count_m<count-k+1){
org_head=org_head->next;
count_m++;
}
//寻找此次反转头的前一个
struct ListNode* org_head_pre=head;
int count_m2=1;
while(count_m2<count-k){
org_head_pre=org_head_pre->next;
count_m2++;
}
//找到反转的尾
int count_n=1;
struct ListNode* org_tail=head;
while(count_n<count){
org_tail=org_tail->next;
count_n++;
}
//找到反转尾的下一个节点
int count_n2=1;
struct ListNode* org_tail_next=head;
while(count_n2<=count){
org_tail_next=org_tail_next->next;
count_n2++;
}
//原地反转法将需要反转的部分链表反转
struct ListNode* pre=org_tail_next;
struct ListNode* cur=org_head;
struct ListNode* next=cur->next;
while(cur!=org_tail_next){
cur->next=pre;
pre=cur;
cur=next;
next=next->next;
}
org_head_pre->next=pre; //链接翻转部分和原来的部分
}
node=node->next;
count++;
}
return head;
}