本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题目
给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
输入: head = [1,2,3,4,5], k = 2
输出: [2,1,4,3,5]
题目解析
思路一
首先判断传入的链表的长度是否大于等于k,如果不是,则返回原始链表, 满足第一个条件的时候,通过三个指针prev、curr、next,分别代表上一个指针、当前指针、下一个指针,我们先将curr指向的下一个节点保存到next,然后将curr的下一个节点指向prev,在将curr与prev的指针往后移动一步,重复前面三个步骤直到k循环次数结束,最后我们可以发现prev始终都是传入链表的表头,curr指向下一个要处理的部分,传入的head就是链表的表尾;curr就是新一组需要处理的链表的表头,再将传入的head指向递归处理的结果,将处理的链表连接起来即可。
var reverseKGroup = function(head, k) {
var idx = 0
var copyHead = head
while (copyHead !== null && idx < k) {
copyHead = copyHead.next
idx++
}
if (idx < k) {
return head
}
var curr = head
var prev = null
var n = k
while (curr !== null && n-- > 0) {
var next = curr.next
curr.next = prev
prev = curr
curr = next
}
head.next = reverseKGroup(curr, k)
return prev
};
思路二
我们使用递归实现一下,这里可以将链表看成一段一段的执行栈,在此寻找找递归的结束和递归的时机
var reverseKGroup = function(head, k) {
//用于进行链表转换
let pre = null,cur = head;
let p = head;
//查找长度是否满足反转的数量
for(let i = 0;i<k;i++){
if(p == null) return head;
p = p.next;
}
//对该k个链表元素进行反转
for(let j = 0;j<k;j++){
let temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
//反转后,head.next已经成为当前反转后链表的最后一个元素,它的指向将是下一个递归的开始点
//而此时pre已经是最后一个元素,cur是下一个范围的第一元素
head.next = reverseKGroup(cur,k);
return pre;
};