思考
题目要求:给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
示例1,中k=2,也就是每两个节点为一组做翻转。
那么我可以把K个一组的链表做为小链表,然后将所有链表首位拼接。
解题思路
- 确定链表长度,小于k个时,直接返回不需要任何操作
- 循环遍历链表,每k个执行一次翻转操作,然后做拼接
- 当遍历指针到达null 或者 剩余链表节点小于 k 的时候退出循环
定义 hair 虚拟头节点保留头指针,pre为待翻转小链表的头指针
pre
hair -> 1 -> 2 -> 3 -> 4 -> 5
pre ------> per != null
hair -> 2 -> 1 -> 3 -> 4 -> 5
pre ----->pre
hair -> 2 -> 1 -> 4 -> 3 -> 5
pre ----> pre
hair -> 2 -> 1 -> 4 -> 3 -> 5 -> null
pre
hair -> 2 -> 1 -> 4 -> 3 -> 5 -> null
代码
var reverse = function (head, k) {
let pre = head, cur = head, cnt = k;
// 判断后续链表是否满足 k 个,如不满足直接返回
while (--k && pre) {
pre = pre.next;
}
if (!pre) return head;
pre = null;
while(cnt--) {
// let next = cur.next;
// cur.next = pre;
// pre = cur;
// cur = next;
[cur.next, pre, cur] = [pre, cur, cur.next];
}
head.next = cur;
return pre;
}
var reverseKGroup = function(head, k) {
// 确定链表长度,小于k个时,直接返回不需要任何操作
if (!head || k < 2) return head;
let hair = new ListNode(-1, head), pre = hair;
while (1) {
// k 个一组的小链表做翻转
pre.next = reverse(pre.next, k);
// pre指针往下走 k 步以确定下一组的链表做翻转
for (let i = 0; i < k && pre; i++) {
pre = pre.next
}
// 但指针走到null节点代表循环结束
if (!pre) break;
}
return hair.next;
};