Leetcode25 k 个一组翻转链表
25 K 个一组翻转链表
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例:
给你这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
说明:
- 你的算法只能使用常数的额外空间。
- 你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/reverse-nodes-in-k-group 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
Solution 1
将每个组的节点保存后分组反转(不合乎常数额外空间)
空间复杂度O(k)
执行用时:12 ms
内存消耗:7.3 MB
struct ListNode *reverseKGroup(struct ListNode *head, int k)
{
struct ListNode **arr = calloc(k * sizeof(struct ListNode *), sizeof(struct ListNode *));
struct ListNode *node = head;
struct ListNode hair;
struct ListNode *step_tail = &hair;
struct ListNode *step_head = head;
int i;
hair.next = head;
while (1)
{
node = step_head;
for (i = 0; i < k; i++)
{
if (node == NULL)
{
step_tail->next = step_head;
return hair.next;
}
arr[i] = node;
node = node->next;
}
step_head = node;
step_tail->next = arr[k - 1];
step_tail = arr[0];
for (i = k - 1; i > 0; i--)
{
arr[i]->next = arr[i - 1];
}
}
}
Solution 2
将每个组的头尾节点记录后,分组反转(思路同Solution 1)
空间复杂度O(1)
执行用时:12 ms
内存消耗:6.5 MB
struct ListNode *reverseKGroup(struct ListNode *head, int k)
{
struct ListNode *node = head;
struct ListNode hair;
struct ListNode *step_tail_before = &hair;
struct ListNode *step_tail_now = &hair;
struct ListNode *step_head_now = head;
struct ListNode *p0, *p1, *p2;
int i;
hair.next = head;
while (step_head_now != NULL)
{
node = step_head_now;
for (i = 0; i < k - 1; i++)
{
node = node->next;
if (node == NULL)
goto END_WHILE;
}
step_tail_now = node;
node = node->next;
// reverse one group
p0 = step_head_now;
p1 = p0->next;
for (i = 0; i < k - 1; i++)
{
p2 = p1->next;
p1->next = p0;
p0 = p1;
p1 = p2;
}
// modify pointer between groups
step_tail_before->next = step_tail_now;
step_tail_before = step_head_now;
step_head_now = node;
}
END_WHILE:
step_tail_before->next = step_head_now;
return hair.next;
}