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)

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

相关推荐
Ricky111zzz15 小时前
leetcode学python记录1
python·算法·leetcode·职场和发展
逆境不可逃17 小时前
LeetCode 热题 100 之 230. 二叉搜索树中第 K 小的元素 199. 二叉树的右视图 114. 二叉树展开为链表
算法·leetcode·职场和发展
wfbcg17 小时前
每日算法练习:LeetCode 15. 三数之和 ✅
算法·leetcode·职场和发展
y = xⁿ17 小时前
【LeetCode Hot100】双指针:分离指针
算法·leetcode
6Hzlia17 小时前
【Hot 100 刷题计划】 LeetCode 41. 缺失的第一个正数 | C++ 原地哈希题解
c++·leetcode·哈希算法
小肝一下18 小时前
每日两道力扣,day6
数据结构·c++·算法·leetcode·双指针·hot100
ByteCraze18 小时前
大四双非春招学习记录-K 个一组反转链表
数据结构·学习·链表
人道领域18 小时前
【LeetCode刷题日记】242.字母异位词
算法·leetcode·职场和发展
旖-旎18 小时前
链表(两两交换链表中的节点)(2)
数据结构·c++·学习·算法·链表·力控
XWalnut18 小时前
LeetCode刷题 day8
算法·leetcode·职场和发展