【路飞】K 个一组翻转链表

268 阅读2分钟

25. K 个一组翻转链表

题目描述:

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

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

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

解题思路:

三点:分组反转跟 92. 反转链表 II思路一样;反转后需要重新连接起来;剩余的节点个数不足k保持原有顺序。

解决剩余的节点个数不足k保持原有顺序:

遍历链表记录链表长度n,需要反转的次数为Math.floor(n/k)

var n = 0;
var flag = head;
while(flag!=null) {flag=flag.next; n++;}
var m = Math.floor(n/k);

解决反转后需要重新连接起来: 记录即将反转区域的前一个节点p,即将反转的第一个节点q。

k组反转链表01.png

反转第一组后:92. 反转链表 II思路

k组反转链表02.png

连接起来,并将p移动到第二组待反转的前一个节点,q移到第二组待反转的第一个节点

k组反转链表03.png

p.next = reverseK(q,k);
p = q;
q = p.next;

代码如下:

/**
 * 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) {
    if(head == null) return head;
    var node = new ListNode(-1);
    node.next = head;
    var p = node, flag = node;

    var q = p.next;
    var n = 0;
    while(flag.next!=null) {flag=flag.next; n++;}
    var m = Math.floor(n/k);

    while(m--){
        p.next = reverseN(q,k);
        p = q;
        q = p.next;
    }
    
    return node.next
};
function reverseN(head,count){
    if(count == 1) return head;
    
    var tail = head.next, p = reverseN(head.next,--count);
    head.next= tail.next;
    tail.next = head;
    return p;
}

解决剩余的节点个数不足k保持原有顺序方法二:

分组反转时,先进行循环遍历待反转区域,当不足k时,不进行反转

function reverseK(head,count){
    if(head == null || head.next == null) return head;
    var n = count;
    var p = head;
    while(--count && p!=null){
        p = p.next;
    }
    if(p== null) return head;//不足k个,返回原顺序
    return _reverseK(head, n);//进行反转

}

整体代码:

/**
 * 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) {
    if(head == null) return head;
    var node = new ListNode(-1);
    node.next = head;
    var p = node, q = p.next;
    while((p.next = reverseK(q,k)) != q) {
        p = q;
        q = p.next;
    }
    return node.next
};
function reverseK(head,count){
    if(head == null || head.next == null) return head;
    var n = count;
    var p = head;
    while(--count && p!=null){
        p = p.next;
    }
    if(p== null) return head;
    return _reverseK(head, n);

}
function _reverseK(head,count){
    if(count == 1) return head;
    
    var tail = head.next, p = _reverseK(head.next,--count);
    head.next= tail.next;
    tail.next = head;
    return p;
}

自述

算法小白一个,记录自己的算法学习之路。如果您发现问题,欢迎留言交流。