题目
- 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
思路
其实你可以多次翻转看做是一次翻转,反复调用不就行了。
另外k个翻转其实就是选取这个子链然后全部翻转呗。
那么这个问题被拆解后就成了一个最简单的翻转链表题了。
由于是个单链表,翻转链表直接用个栈即可,一次AC ,so easy!
代码
public ListNode reverseKGroup(ListNode head, int k) {
Stack<ListNode> stack = new Stack<>();
ListNode ret = null;
// p用来遍历链表 lastTail作为上一个链表的尾部节点
ListNode p = head, lastTail = null;
// 有节点则执行
while (p != null) {
// 截取一个长度为k的链表放入栈,准备倒转
for (int i = 0; i < k && p != null; i++) {
stack.add(p);
p = p.next;
}
// 凑齐了k个就翻转
if (stack.size() == k) {
// 翻转后子链的头
ListNode newHead = stack.pop();
// 如果之前已经有链翻转过了,那就要把前面链的结尾链接到下一个链的头
if (lastTail != null) {
lastTail.next = newHead;
}
// 子链的头
head = newHead;
// 第一次翻转的头要作为最终返回的头
if (ret == null) {
ret = head;
}
// 开始翻转子链
while (!stack.isEmpty()) {
ListNode pop = stack.pop();
newHead.next = pop;
newHead = pop;
}
// 存好这个子链的尾巴
lastTail = newHead;
// 把这个子链的尾巴链接上后面链的第一个节点
newHead.next = p;
}
}
return ret;
}