K个一组翻转链表
要求
一个链表,每 k 个节点一组进行翻转,返回翻转后的链表。 k 是一个正整数,它的值小于或等于链表的长度。 如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
进阶: 可以设计一个只使用常数额外空间的算法来解决此问题吗? 不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
思路
思路都写在代码注释里啦
代码
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
var reverseKGroup = function (head, k) {
// 举例:1->2->3->4->5->6->7->8->9 k=4
// 当传进来的head为空,直接return出去
if (!head) return null;
// 创建两个指针,指向head的前一个节点
let ret = new ListNode(-1, head),
pre = ret;
do {
// 第一次翻转
// 此时,链表为:-1(ret,pre)->1->2->3->4->5->6->7->8->9
// pre.next = reverse(1->2->3->4,4)
// 经过reverse函数的处理,链表为:-1(ret,pre)->4->3->2->1->5->6->7->8->9
pre.next = reverse(pre.next, k);
// i<k且pre不为空,一直for
for (let i = 0; i < k && pre; i++) {
pre = pre.next;
}
// pre为空,跳出循环
if (!pre) break;
// for出来后,链表为-1(ret)->4->3->2->1(pre)->5->6->7->8->9
} while (1)
// 循环结束,链表为-1(ret)->4->3->2->1->8->7->6->5->9
return ret.next;
};
var reverse = function (head, n) {
let pre = head,
cur = head,
con = n;
// 此处while为了判断传入的链表是否够n值翻转
while (--n && pre) {
pre = pre.next;
}
// 不够n值翻转,return传进来的值
if (!pre) return head;
// 满足n值翻转,设pre为null,进行解构赋值
pre = null;
while (con--) {
[cur.next, pre, cur] = [pre, cur, cur.next]
}
// 经过while里面的解构赋值处理,此时的cur指向5
// 此处head.next = cur,即为:1.next = 5
head.next = cur;
// return 4 (此时链表关系为:4->3->2->1->5)
return pre;
}