25. K 个一组翻转链表
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例 :
给定这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
说明 :
你的算法只能使用常数的额外空间。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
/*
把原链表分成若干小段,然后分别对其进行翻转,
那么肯定总共需要两个函数,一个是用来分段的,
一个是用来翻转的,我们就以题目中给的例子来看,
对于给定链表 1->2->3->4->5,一般在处理链表问题时,
我们大多时候都会在开头再加一个 dummy node,
因为翻转链表时头结点可能会变化,为了记录当前最新的头结点的位置而引入的 dummy node,
那么我们加入 dummy node 后的链表变为 - 1->1->2->3->4->5,如果k为3的话,
我们的目标是将 1, 2, 3 翻转一下,那么我们需要一些指针,pre 和 next 分别指向要翻转的链表的前后的位置,
然后翻转后 pre 的位置更新到如下新的位置:
- 1->1->2->3->4->5
| | |
pre cur next
- 1->3->2->1->4->5
| | |
cur pre next
*/
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
using namespace std;
struct ListNode
{
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k)
{
if (!head || k == 1)
return head;
ListNode *dummy = new ListNode(-1), *pre = dummy, *cur = head;
dummy->next = head;
for (int i = 1; cur; ++i)
{
if (i % k == 0)
{
pre = reverseOneGroup(pre, cur->next);
cur = pre->next;
}
else
{
cur = cur->next;
}
}
return dummy->next;
}
ListNode* reverseOneGroup(ListNode* pre, ListNode* next)
{
ListNode *last = pre->next, *cur = last->next;
while (cur != next)
{
last->next = cur->next;
cur->next = pre->next;
pre->next = cur;
cur = last->next;
}
return last;
}
};
ListNode* CreateListNode(int arr[], int n)
{
ListNode* head;
head = new ListNode(arr[0]);
ListNode* cur;
cur = head;
for (int i = 1; i < n; i++)
{
cur->next = new ListNode(arr[i]);
cur = cur->next;
}
return head;
}
int main()
{
int k;
cin >> k;
int n;
cin >> n;
int i;
int a[100];
for (i = 0; i < n; i++)
{
scanf("%d", &a[i]);
}
ListNode* head = CreateListNode(a, n);
ListNode* result = Solution().reverseKGroup(head,k);
while (result != NULL)
{
printf("%d ", result->val);
result = result->next;
}
system("pause");
return 0;
}
浙公网安备 33010602011771号