leetcode hot100 25. K 个一组翻转链表 hard

把这个问题拆解为三个步骤

  1. 找到待翻转的区间:从当前位置开始计数,数出 kkk 个节点。
  2. 如果不足 kkk 个,直接返回,不翻转。
  3. 翻转这 kkk个节点:使用我们熟悉的"翻转链表"逻辑。
  4. 连接前后区间:将翻转后的局部链表重新接回原链表中
python 复制代码
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:


        prehead = ListNode(-1)
        prehead.next = head

        # 当前 k个节点小组的前驱节点
        pre = prehead   # 初始值
        
        # 推进head
        while head:

            # 先组内推进,尾指针前进K个
            tail = pre
            for i in range(k):
                tail = tail.next
                if not tail:    # 即使不足 k 个,也要从最开始的 prehead 返回,而不是当前组pre.next
                    return prehead.next

            # 足k个,记录下一组的起点
            nxt = tail.next

            # 翻转这一小组 [head, tail]
            # 定义一个子函数来处理局部翻转
            head, tail = self.reverse(head, tail)

            # 把翻转后的子链表接回主链表
            pre.next = head
            tail.next = nxt

            # 指针移动,准备处理下一组
            pre = tail
            head = tail.next

        return prehead.next

    # 局部翻转辅助函数
    def reverse(self, head: ListNode, tail: ListNode):
        if not head or not tail:
            return None

        pre = None   # 头节点前面的设一个空节点,先不用指向头节点,因为但反过来之后,头节点就指向none
        cur = head

        while pre != tail:
            tmp = cur.next # 暂存后继节点 cur.next
            cur.next = pre  # 修改 next 引用指向
            pre  = cur
            cur = tmp

        # 翻转后,原来的 tail 变成了新头,原来的 head 变成了新尾
        return tail, head

时间复杂度:O(n)O(n)O(n)

虽然有嵌套循环,但每个节点实际上只被访问了常数次(一次是定位 tail,一次是翻转)。
空间复杂度:O(1)O(1)O(1)

只额外使用了常数个指针,属于原地翻转。

相关推荐
菜菜小狗的学习笔记1 小时前
剑指Offer算法题(四)链表
数据结构·算法·链表
We་ct2 小时前
LeetCode 148. 排序链表:归并排序详解
前端·数据结构·算法·leetcode·链表·typescript·排序算法
x_xbx4 小时前
LeetCode:2. 两数相加
算法·leetcode·职场和发展
_日拱一卒4 小时前
LeetCode:最长连续序列
算法·leetcode·职场和发展
重生之后端学习5 小时前
287. 寻找重复数
数据结构·算法·leetcode·深度优先·图论
实心儿儿6 小时前
算法7:两个数组的交集
算法·leetcode·职场和发展
sheeta19987 小时前
LeetCode 每日一题笔记 日期:2025.03.19 题目:3212.统计X和Y频数相等的子矩阵数量
笔记·leetcode·矩阵
Storynone7 小时前
【Day28】LeetCode:509. 斐波那契数,70. 爬楼梯,746. 使用最小花费爬楼梯
python·算法·leetcode
Book思议-8 小时前
【数据结构实战】链表找环入口的经典问题:快慢指针法
c语言·数据结构·算法·链表
liuyao_xianhui8 小时前
优选算法_两数之和_位运算_C++
java·开发语言·数据结构·c++·算法·链表·动态规划