算法学习记录(八十四)

72 阅读1分钟

25. K 个一组翻转链表

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

k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

image.png 解:

  1. 剩余节点不足K个就不反转,所以得获取链表长度,遍历一遍记录长度。
  2. 以K = 3为例,从上图可以看出,每翻转k个节点后,就把上轮的头节点的next指向本轮的尾节点,每反转一个节点就把剩余长度减一
  3. 当链表遍历完或者不足k个就跳出循环
  4. 还要改变最后一轮中头节点的next指向,所以如果链表已经遍历完了就指向空,否则指向未遍历到的节点
const reverseKGroup = function(head, k) {
    // 链表长度
    let len = 0
    // 当前节点
    let cur = head
    while (cur) {
        cur = cur.next
        len++
    }
    cur = head
    let preNode = null
    // 头节点
    let headNode = null
    // 尾节点
    let tailNode = null
    // 结果节点
    let resNode = null
    while (cur && len >= k) {
        // 记录上一轮头节点
        const preHead = headNode
        for (let i = 0; i < k; i++) {
            // 本轮头尾节点
            if (i === 0) headNode = cur
            if (i === k - 1) tailNode = cur
            const temp = cur.next
            cur.next = preNode
            preNode = cur
            cur = temp
            len--
        }
        // 结果节点赋值为第一轮反转的尾节点
        if (!resNode) resNode = tailNode
        // 把上一轮头节点的next指向本轮的尾节点
        if (preHead) preHead.next = tailNode
    }
    // 修改最后一轮结束后的头节点next指向
    cur ? headNode.next = cur : headNode.next = null
    return resNode
};