携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情
K个一组翻转链表
给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。 k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。 你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
来源:力扣(LeetCode) 链接:leetcode.cn/problems/re…
分析
根据题目获取题意
- k个一组进行翻转,如果总节点数不是k的整数倍,剩余节点保持原有顺序
- 不能简单的改变链表的值,要实际操作链表节点的指针
问题拆解
- 链表的翻转,只不过此处的链表是链表的一个子集,在翻转链表时,一般使用的是有头节点的链表,这里的头结点指的是没有内容,指针指向链表第一个元素的节点。因为题目中的链表没有头结点,所以在翻转的时候,需要加上这个空节点之后进行翻转
- 翻转前,确定需要翻转的链表节点的范围,根据k值,循环确定需要翻转的链表节点
- 翻转时,要注意有头结点的子链表的相关指针与原来链表的指针的变化,因为k个一组循环翻转,可以比较容易想到需要设置两个指针LR来标识已翻转部分的最左的节点和最右的节点,那剩下的最右的节点一直到链表的尾节点就是没有翻转的部分
- 翻转后,链表分为两部分,已翻转部分和未翻转部分,知道k个一组循环翻转结束后,即可得到问题的答案
代码
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
var reverseKGroup = function(head, k) {
let thead = new ListNode(0)
thead.next = head
let pre = thead
let end = thead
while (end.next !== null) {
for (let i = 0; i < k && end !== null; i++) {
end = end.next
}
if (end == null) break
let start = pre.next
let next = end.next
end.next = null
pre.next = reverse(start)
start.next = next
pre = start
end = pre
}
return thead.next
};
function reverse(head) {
if (head === null) {
return head
}
let cur = head
let pre = null
while (cur) {
[cur.next, pre, cur] = [pre, cur, cur.next]
}
return pre
}
总结
- 本题的难度系数为困难,链表这类题目,解法比较套路,难度高的是不同解法的合并,相比于其他数据结构,能玩出的花活有限,熟能生巧吧
- 今天又是有收获的一天