在问 · 算法题解

25. K 个一组翻转链表

困难链表分组迭代反转力扣原题 ↗

题目描述

输入链表的头节点 head 和正整数 k,链表用数组表示。k 不超过链表长度。

从头开始每 k 个节点分成一组,把每组内的节点顺序倒过来。最后不足 k 个的节点保持原顺序。

必须调整节点本身的连接,不能只换节点里的值。返回处理后链表的头节点。

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

解释:分组为 [1,2]、[3,4]、[5],前两组各自翻转,最后一组不足 2 个不动。

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

解释:分组为 [1,2,3]、[4,5],只翻转第一组。

数据范围

  • 链表节点数记为 n
  • 1 <= k <= n <= 5000
  • 0 <= Node.val <= 1000

进阶:能否只用 O(1) 的额外空间完成?

解题思路:分组迭代反转

先检查一组是否有 k 个节点,保存组后节点;用标准指针反转这段区间,再接回前缀。

为什么正确

group_prev 前面的组已翻转;每次只翻转完整的 k 个节点。

复杂度分析

时间 O(n),额外空间 O(1)。

易错点

必须先确认组长;不足 k 个的部分不能翻转。

参考代码

Python、Java、C++、Go、JavaScript、TypeScript 六种语言,逻辑一致。

class Solution:
    def reverseKGroup(self, head, k):
        dummy = ListNode(0, head)
        group_prev = dummy
        while True:
            kth = group_prev
            for _ in range(k):
                kth = kth.next
                if kth is None:
                    return dummy.next
            group_next = kth.next
            prev, cur = group_next, group_prev.next
            while cur is not group_next:
                nxt = cur.next
                cur.next = prev
                prev, cur = cur, nxt
            old_head = group_prev.next
            group_prev.next = kth
            group_prev = old_head

载入编辑器,自己跑一遍 →

其他解法

两种方法都是 O(n) 时间;递归版结构更简单但占 O(n/k) 栈空间,迭代版需要手动维护组前后的连接,额外空间 O(1)。

解法 2:递归分组反转 时间 O(n),空间 O(n/k)

从 head 向后走 k 步,不足 k 个节点就原样返回 head。否则走到的节点 node 是下一组的开头,先递归处理 node 之后的部分,得到已翻转的剩余链表 prev。再把当前组的 k 个节点逐个头插到 prev 前面,最后返回新的组头。

不需要哑节点和 group_prev,组与组的衔接由返回值自动完成,容易写对。递归深度为组数 n/k,不满足题目进阶要求的 O(1) 额外空间。

import sys

class Solution:
    def reverseKGroup(self, head, k):
        sys.setrecursionlimit(10000)
        node = head
        for _ in range(k):
            if node is None:
                return head
            node = node.next
        prev = self.reverseKGroup(node, k)
        cur = head
        for _ in range(k):
            nxt = cur.next
            cur.next = prev
            prev, cur = cur, nxt
        return prev

链表 专题的其他题目

查看 链表 全部题目 →