https://leetcode.com/problems/reverse-nodes-in-k-group/description/
题意:给一个链表和一个正数k,将链表划分成多个长度为k的链,将这些链反转。
思路:先想一个反转链表的算法:在k个结点中,每次从起始出发走i步(i从k到1),然后将这个结点插入新链即可。
然后对整条链,用begin记录前驱,end记录小段链表的末尾,即end = begin + k
,然后每次反转(begin,end]
的部分,直到end到达全链末尾。
需要总结的是,处理连续状态时需要“留有余地”,不要全部用满,本题中的体现就是反转链表时取的是开区间(begin,end]
,即头部begin并未参与反转,这样就能记录链的前驱,而不至于反转之后衔接不上。同理设辅助头结点也是这个思路。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reverseKGroup(self, head, k):
"""
:type head: ListNode
:type k: int
:rtype: ListNode
"""
if k == 1 : #k等于1时直接返回原链
return head
Head = ListNode(0) #辅助头结点
Head.next = head
begin = Head #段起始
end = Head #段结束
while begin and end: #都非空时
count = 0
while count < k and end: #end前进k步(如果存在的话)
end = end.next
count += 1
if not end: #end走到末尾即退出
break
begin.next = self.reverse(begin.next, k) #begin的next开始,反转k个结点,然后记录下新的后继
#反转结束后end和begin都可能变化,更新
end = begin
for _ in range(k):
end = end.next
begin = end
return Head.next
def reverse(self, head, k): #辅助函数,将head为头的k个结点反转,返回反转后的头
Head = ListNode(0)
Head.next = head
work = Head
Next = None
for count in range(k, 0, -1): #每次找倒数第count个结点(count从k到1)
find = head
for _ in range(count-1):
find = find.next
if count == k: #保存本段链的后继
Next = find.next
work.next = find
work = work.next
find = Head
for _ in range(k):
find = find.next
find.next = Next #将本段链的后继衔接
return Head.next