Leetcode-25.K个一组翻转链表
核心还是掌握链表的反转
# Definition for singly-linked list.# class ListNode:# def __init__(self, val=0, next=None):# self.val = val# self.next = nextclass Solution:def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:dummy=ListNode(0,head)pre=dummywhile True:end =prefor _ in range(k):end=end.nextif not end:return dummy.nextstart=pre.nextnext_group=end.nextcur=startprev=next_groupwhile cur!=next_group:nxt=cur.nextcur.next=prevprev=curcur=nxtpre.next=endpre=startreturn dummy.next
1. 整条链表反转(一次性从头到尾)
经典的三指针法:
-
prev
:保存反转后部分的头(初始为None
) -
curr
:当前正在处理的节点 -
next
(或nxt
):提前保存curr.next
,防止链表断开
反转过程:
prev = None curr = head while curr: nxt = curr.nextcurr.next = prev prev = curr curr = nxt
✅ 只要 3 个指针 就够,空间 O(1)。
2. 反转一段子链(已知子链的首尾)
除了 prev/curr/nxt
三个工作指针,还要额外 2 个锚点:
-
sub_prev
:子链前驱(前一段的尾) -
sub_next
:子链后继(后一段的头)
反转步骤:
-
用
sub_prev
和sub_next
把子链分离出来 -
用
prev/curr/nxt
反转子链 -
反转完接回
sub_prev → 新头
,新尾 → sub_next
✅ 这里需要 3 个工作指针 + 2 个锚点 = 5 个指针。
3. K 个一组反转
这是你现在问的情况,步骤是:
-
用
pre
找到本组前驱 -
用
end
找到本组尾巴(走 k 步) -
用
next_group = end.next
保存下一组的起点 -
用
prev/curr/nxt
反转[start, end]
-
反转完接回并让
pre
移到新尾(原来的 start)
常用指针:
-
跨组锚点:
pre
、end
、next_group
(3 个) -
反转工作:
prev
、curr
、nxt
(3 个)
✅ 总共 固定 6 个指针,不随 k 增加而增加。