*思路:
- 先将整体链表反转:0,1,2,3,4,5,6,7 ==> 7,6,5,4,3,2,1,0
- 再从链表头以K个节点为一组反转:5,6,7,4,3,2,1,0 -> 5,6,7,2,3,4,1,0
- 再进行整体反转得到 0,1,4,3,2,7,6,5
- **/
#include <stdio.h>
#include <stdlib.h>
// 链表节点的定义
struct ListNode {
int val;
struct ListNode *next;
};
// 创建链表节点
struct ListNode* createNode(int val) {
struct ListNode* newNode = (struct ListNode*)malloc(sizeof(struct ListNode));
newNode->val = val;
newNode->next = NULL;
return newNode;
}
// 销毁链表
void destroyList(struct ListNode* head) {
struct ListNode* current = head;
while (current != NULL) {
struct ListNode* temp = current;
current = current->next;
free(temp);
}
}
// 反转链表
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode* prev = NULL;
struct ListNode* current = head;
while (current != NULL) {
struct ListNode* nextNode = current->next;
current->next = prev;
prev = current;
current = nextNode;
}
return prev;
}
// 从头开始每K个一组反转
struct ListNode* reverseKFromEnd(struct ListNode* head, int k) {
if (head == NULL || k <= 1) {
return head;
}
// 先整体反转链表
struct ListNode* reversedHead = reverseList(head);
// 从头开始每K个一组反转
struct ListNode* newHead = NULL;
struct ListNode* prevTail = NULL;
struct ListNode* current = reversedHead;
while (current != NULL) {
struct ListNode* groupHead = current;
struct ListNode* groupTail = current;
// 找到当前组的尾节点
for (int i = 1; i < k && groupTail != NULL; i++) {
groupTail = groupTail->next;
}
// 如果当前组长度小于K,则无需反转,直接跳出循环
if (groupTail == NULL) {
break;
}
// 记录下一组的起始节点
struct ListNode* nextGroupHead = groupTail->next;
// 反转当前组
struct ListNode* prev = nextGroupHead;
struct ListNode* currentGroupNode = groupHead;
while (currentGroupNode != nextGroupHead) {
struct ListNode* nextNode = currentGroupNode->next;
currentGroupNode->next = prev;
prev = currentGroupNode;
currentGroupNode = nextNode;
}
// 将反转后的组接到结果链表上
if (prevTail != NULL) {
prevTail->next = groupTail;
} else {
newHead = groupTail;
}
// 更新prevTail,准备连接下一组
prevTail = groupHead;
// 将current指向下一组的起始节点
current = nextGroupHead;
}
// 再次整体反转链表
return reverseList(newHead);
}
// 打印链表
void printList(struct ListNode* head) {
struct ListNode* current = head;
while (current != NULL) {
printf("%d -> ", current->val);
current = current->next;
}
printf("NULL\n");
}
int main() {
// 创建链表
struct ListNode* head = createNode(0);
struct ListNode* current = head;
for (int i = 1; i < 8; i++) {
current->next = createNode(i);
current = current->next;
}
// 打印原始链表
printf("Original list: ");
printList(head);
// 反转链表
int k = 3;
struct ListNode* reversedHead = reverseKFromEnd(head, k);
// 打印反转后的链表
printf("Reversed list: ");
printList(reversedHead);
// 销毁链表
destroyList(reversedHead);
return 0;
}