「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战」
K 个一组翻转链表
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
进阶:
你可以设计一个只使用常数额外空间的算法来解决此问题吗? 你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
示例1:
输入: head = [1,2,3,4,5], k = 2
输出: [2,1,4,3,5]
递归法
思路
这道题我们可以采取递归的思路来进行处理,我们只需要吧链表拆分成k个节点的链表一,以及剩下的链表二部分(即k节点的下一个节点,我们用next表示)。
我们需要一个链表反转函数「206. 反转链表」来将我们的链表一进行反转。这样我们就得到了第一组反转后的结果。 接下来我们需要将剩余的链表二继续递归调用来得到后续的结果。
这样我们就通过多次调用函数,每次只处理k个结果,最后将左右的结果首尾相连就得到了最终的值。 因为要收尾相连,而链表无法直接获取最后一个节点。所以我们要在这个过程中标记每组的起点start和终点end。
当我们截取到k个节点的链表一时,我们标记了他的起点start和终点end,当他完成翻转后,那么收尾发生交换,此时start标记的节点是尾结点。我们只需要将链表一翻转后的尾结点(start)接上函数的返回结果res,即start.next=reverseKGroup(next, k)
当最后的next链表不足k个节点时则直接返回next,无需处理
最后我们就得到了以下结果
function reverseList(head) {
if (!head||!head.next) return head
if (head.next) {
var next = head.next
var res = reverseList(next)
next.next = head
head.next = null
return res
}
}
var reverseKGroup = function (head, k) {
let start = head;
let end = head;
let next = null;
for (var i = 0; i < k-1; i++) {
if (end && !end.next) {
return start
}
end = end.next;
}
next = end.next
end.next = null
var res = reverseList(start)
if (next) {
start.next = reverseKGroup(next,k)
}
return res
};