原理:从头开始,每数够K个数就将其翻转,不够不反转
#include<stdio.h>
#include <stdlib.h>
struct ListNode {
int val;
struct ListNode *next;
};
//反转函数
//pre:反转之前的一个节点,end:第k组反转之前的指针
struct ListNode* reverse(struct ListNode* pre, struct ListNode* end,struct ListNode* next){
struct ListNode* start = pre->next; //第k组开始反转的指针
struct ListNode* last; //下一个节点
struct ListNode* startTemp = start; //第K组开始节点的备份
while(start != end){
last = start ->next;
start ->next = next;
next = start;
start = last;
}
//将源第K组end节点接到第K-1组后边
end ->next = next;
pre ->next = end;
//现在需要将pre定位到原来的end,也就是原来的start
return startTemp;
}
//数够k个就反转
struct ListNode* reverseKGroup(struct ListNode* head, int k){
//标记次数,遇到k就重置为0;
int number = 0;
//生成一个虚拟头指针
struct ListNode newhead; //虚拟头节点的结构体
struct ListNode* virtualhead01 = &newhead,*virtualhead = &newhead; //virtualhead01虚拟头节点的复制,作为返回值使用
struct ListNode *pre; //上一个节点保存
newhead.next = head;
if(head == NULL || head ->next ==NULL){
return head;
}
while(head != NULL){
number++;
pre = head;
head = head ->next;
//数够k个节点,翻转
if(number == k){
virtualhead = reverse(virtualhead,pre,head);
number=0;
}
}
return virtualhead01->next;
}
struct ListNode* init(struct ListNode** head,int *w,int size){
int i = 1;
struct ListNode *temp01, *temp;;
(*head) =(struct ListNode*)malloc(sizeof(struct ListNode));
(*head)->val = w[0];
(*head)->next = NULL;
temp01 = *head;
for(i =1; i< size; i++){
temp=(struct ListNode*)malloc(sizeof(struct ListNode));
temp->val = w[i];
temp->next = NULL;
temp01->next = temp;
temp01 = temp;
}
return *head;
}
void print(struct ListNode* head){
while(head != NULL){
printf("%d ", head->val);
head = head ->next;
}
printf("\n");
}
int main(){
struct ListNode* head;
int w[5] = {1,2,3,4,5};
int k= 2;
head = init(&head,w,5);
head = reverseKGroup(head,k);
print(head);
return 0;
}
原理:
方法二:
//数够k个就反转
struct ListNode* reverseKGroup(struct ListNode* head, int k){
//标记次数,遇到k就重置为0;
int number = 0;
//生成一个虚拟头指针
struct ListNode newhead; //虚拟头节点的结构体
struct ListNode *pre = &newhead;
struct ListNode *end = &newhead; //virtualhead01虚拟头节点的复制,作为返回值使用
newhead.next = head; //无论怎么变化,newhead.next 一定是新头节点
while(end->next != NULL){
for(number =0; number< k && end != NULL) end = end->next;
if(end == NULL) break;
struct ListNode *start = pre ->next;
struct ListNode *next = end ->next;
end ->next = NULL;
//数够k个节点,翻转
pre->next = reverse(start);
start->next = next;
pre = start;
end = pre;
}
return newhead.next;
}
第三种方法:栈,每次取栈顶元素,实现翻转
struct ListNode* reverseKGroup(struct ListNode* head, int k){
//创建栈
struct ListNode* queen[3];
int rear = -1;
//生成一个虚拟头指针
struct ListNode newhead; //虚拟头节点的结构体
struct ListNode *pre = &newhead;
struct ListNode *temp= head; //第一个节点的复制
newhead.next = head; //无论怎么变化,newhead.next 一定是新头节点
while(true){
int count =0;
while(temp != NULL && count <k){
//入栈
queen[++rear] = temp;
temp = temp->next;
count++;
}
if(count != k)
{
pre ->next = head;
break;
}
//出栈
while(rear != -1){
pre->next = queen[rear--];
pre = pre ->next;
}
pre->next = temp;
head = temp;
}
return newhead.next;
}
结果: