LeetCode题解-25. K个一组翻转链表

题目描述

给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。

k 是一个正整数,它的值小于或等于链表的长度。

如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

示例:

给定这个链表:1->2->3->4->5

当 k = 2 时,应当返回: 2->1->4->3->5

当 k = 3 时,应当返回: 3->2->1->4->5

说明

  • 你的算法只能使用常数的额外空间。
  • 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

思路

每k个节点翻转一次,保存下这k个节点翻转后的头节点和尾节点,因为需要和下一段k个节点的链表相连接。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public ListNode reverseKGroup(ListNode head, int k) {
if (head == null || head.next == null) {
return head;
}
int length = 0;
ListNode l = head;
// 获取链表长度
while (l != null) {
length++;
l = l.next;
}
// 如果k大于链表长度,则直接返回,毋需翻转
if (k > length) {
return head;
}
int count = length / k;
ListNode next = null;
ListNode current = head;
// 每段翻转后的链表的头节点
ListNode[] rHeads = new ListNode[count];
// 每段翻转后的链表的尾节点
ListNode[] rEnds = new ListNode[count];
int index = 0;
while (count-- > 0) {
// 保存尾节点
rEnds[index] = current;
ListNode prev = null;
// 翻转链表
for (int i = 0; i < k; i++) {
next = current.next;
current.next = prev;
prev = current;
current = next;
}
// 保存头节点
rHeads[index] = prev;
index++;
}
int temp = length / k;
// 尾节点连接头节点
for (int f = 0; f < temp - 1; f++) {
ListNode h = rEnds[f];
h.next = rHeads[f + 1];
}
// 最后一个尾节点连接链表剩余长度不足k的节点
rEnds[temp - 1].next = next;
return rHeads[0];
}