Files
LeetCode/链表/10. K 个一组翻转链表.md
T
2025-10-03 23:02:46 +08:00

101 lines
2.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# K 个一组翻转链表
## 题目
给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
示例 1:
输入:head = [1,2,3,4,5], k = 2
输出:[2,1,4,3,5]
示例 2:
输入:head = [1,2,3,4,5], k = 3
输出:[3,2,1,4,5]
提示:
链表中的节点数目为 n
1 <= k <= n <= 5000
0 <= Node.val <= 1000
进阶:你可以设计一个只用 O(1) 额外内存空间的算法解决此问题吗?
## 思路
- 分解
- 判定
- 区域翻转
## 代码
```java
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
// Init: DummyHead, begin, end
ListNode dummyHead = new ListNode(-1);
dummyHead.next = head;
ListNode begin = dummyHead;
ListNode end = dummyHead;
// Traverse 1: end -> null
while (end.next != null) {
// Traverse 2: Find K
int cnt = 0;
while (end != null && cnt < k) {
end = end.next;
cnt ++;
}
if (end == null) {
break;
}
// Begin [pA...... end ] pB
// Begin [end...... pA ] pB
ListNode pA = begin.next;
ListNode pB = end.next;
// Operation
end.next = null;
reverse(pA);
begin.next = end;
pA.next = pB;
begin = end = pA;
}
return dummyHead.next;
}
void reverse(ListNode head) {
ListNode dummyHead = new ListNode(-1);
ListNode cur = head;
while (cur != null) {
// dummyHead -> new -> others
ListNode tmp = dummyHead.next;
dummyHead.next = cur;
cur = cur.next;
dummyHead.next.next = tmp;
}
}
}
```