题解 | #链表中的节点每k个一组翻转#
链表中的节点每k个一组翻转
http://www.nowcoder.com/practice/b49c3dc907814e9bbfa8437c251b028e
思路:翻转K个节点区间内的链表,然后获得新的区间头尾结点,再与前后区间拼接。
function reverseKGroup( head , k ) {
const root = { next: head }; // 虚拟节点,保存头节点
let prev = root; // 上一部分的尾节点
let start = head; // 翻转区间的开始节点
let end = head; // 翻转区间的结束节点
let count = 1; // 用于翻转计数
while(end) {
if(count === k) {
// 缓存
const cacheDoneEnd = start; // 缓存当前区间翻转后的尾结点,即为未翻转前的开始节点
/** 区间翻转开始 **/
// 翻转前区间为:prev -> n1(cacheDoneEnd) -> ... -> nk -> cacheNextStart
// 翻转后:prev -> nk -> ... -> n1(cacheDoneEnd) -> cacheNextStart
// 下一区间:prev(n1(cacheDoneEnd)) -> cacheNextStart(start) -> ...
let tp = end.next; // 翻转后的节点指向的节点,第一个翻转的节点变为最后一个节点,所以要指向下一区间的开始节点
while(count > 1) {
// 当前节点指向前一个节点
// 前一个节点更新为当前节点
// 当前节点更新为下一个节点
[start.next, tp, start] = [tp, start, start.next];
count--; // 翻转 k - 1 次,即 k 个节点
}
start.next = tp; // 将翻转后的最后一个节点指向前一个节点
/** 区间翻转完成 **/
// 更新下一区间
prev.next = start; // 将上一区间的尾节点指向当前区间的开头节点,start 迭代到区间的末尾节点,因为链表翻转,又成为区间的开始节点
prev = cacheDoneEnd; // 将当前区间的尾结点更新为下一区间的上一区间尾结点
start = prev.next; // 更新下一区间的开始节点
end = start; // 重新设置下一区间的尾节点
} else {
// 区间范围不足,扩大区间
end = end.next;
count++;
}
}
return root.next;
}
查看7道真题和解析

