题目描述
给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序。
示例 :
给定这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
说明 :
你的算法只能使用常数的额外空间。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
ListNode 结构
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
解决方法
使用 4 个指针反转链表
start 下一次循环的开始节点
kStep 提前走 k 步
cur 当前要移动的节点
pre 固定的开始节点
例如:list = 1 -> 2 -> 3 -> 4 -> 5, k = 3
首先使用虚拟头节点简化操作
dummy -> 1 -> 2 -> 3 -> 4 -> 5
第一次反转链表过程如下
dummy -> 1 -> 2 -> 3 -> 4 -> 5
pre cur kStep
start
dummy -> 2 -> 3 -> 1 -> 4 -> 5
pre cur kStep start
dummy -> 3 -> 2 -> 1 -> 4 -> 5
pre cur start
kStep
第二次反转遍历过程如下
dummy -> 3 -> 2 -> 1 -> 4 -> 5 -> null
pre start kStep
kStep 为 null 退出循环
public ListNode reverseKGroup(ListNode head, int k) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode start = dummy;
while (true) {
ListNode kStep = start, pre = start, cur;
start = pre.next;
for (int i = 0; i < k && kStep != null; i++)
kStep = kStep.next;
if (kStep == null)
break;
for (int i = 0; i < k – 1; i++) {
cur = pre.next;
pre.next = cur.next;
cur.next = kStep.next;
kStep.next = cur;
}
}
return dummy.next;
}
本文首发:https://lierabbit.cn/2018/09/…