前端算法小白攻略6-leetcode(K 个一组翻转链表)

150 阅读2分钟

前言

反转整条链表我们搞定之后,其实K个一组翻转链表就是对每k个节点进行反转,这样理解起来就比较颗粒化了,那么让我们开始解题吧!

题目描述

K 个一组翻转链表: 给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。

k 是一个正整数,它的值小于或等于链表的长度。

如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例 1:

输入: head = [1,2,3,4,5], k = 2
输出: [2,1,4,3,5]

解题思路

  1. 看示例1我们可以得出:k=2时,即每两个节点进行反转之后链表,1和2,3和4反转,最后剩余节点数小于k,直接连接;

加入代码

var reverseKGroup = function(head, k) {
    if(!head) return null;
    let ret = new ListNode(-1,head),pre = ret; // 1、反转时头节点可能会发生变化,所以用虚头,最后返回ret.next即为我们的新链表
    do{
        pre.next = reverse(pre.next,k); // 2、使用do while先进行一次反转,
        while(k-- && pre) {     // 3、反转后让pre指针移动k个节点
            pre = pre.next;
        }
        if(!pre) break; // 4、如果移动过程中pre为null说明剩余节点不足反转跳出循环体
    }while(1);
    return ret.next;
};

var reverse = function(head, n) {
    let pre = head, cur = head,con = n;
    while(--con && pre){ // 5、因为pre已经在待反转的第一个节点,所以用--con,先减1在移动con次pre指针
        pre = pre.next;
    }
    if(!pre) return head; // 6、如果移动过程中pre为null说明剩余节点不足反转,直接返回head不必再进行反转;
    pre = null;           // 7、此处开始反转链表的操作
    while(n--) {
        let next = cur.next;
        cur.next = pre;
        pre = cur;
        cur = next;
    }
    head.next = cur;  // 8、因为head节点为反转后节点的尾节点,用尾节点连接下一个待反转节点cur
    return pre;
}