给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例 :
给定这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
说明 :
你的算法只能使用常数的额外空间。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
思路
- 已经翻转的部分和剩下的链表连接起来
(1)用pre 来表示需要翻转部分链表的前驱;
(2)每次翻转前,首先确定翻转的范围,需要进行k次循环,
start (= pre.next) 和 end(k循环得到) 来确定翻转区间;
(3)对需要翻转的链表进行翻转,pre.next = 翻转好的链表;
(4)更新pre,end.
def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
if not head or not head.next:
return head
new_head = ListNode(0)
new_head.next = head
pre, end = new_head, new_head
while end.next:
i = 0
while i < k and end != None:
end = end.next
i += 1
if end == None:
break
start = pre.next
nxt = end.next
end.next = None
pre.next = self.reverse(start)
start.next = nxt
pre = start
end = pre
return new_head.next
def reverse(self, head):
pre = None
cur = head
while cur:
nxt = cur.next
cur.next = pre
pre = cur
cur = nxt
return pre
- 使用栈存储需要翻转的节点
(1)对要翻转的部分进行k次循环,同时要保证这部分长度是大于k的;
(2)如果剩下的链表数不够k,则跳出循环,将已经翻转好的部分和剩下的链表相连;
(3)如果够k,则对栈内的元素进行出栈,将已经翻转好的部分和这些出栈的节点依次相连;
(4)更新前驱节点和头结点。
def reverseKGroup2(self, head: ListNode, k: int) -> ListNode:
if not head or not head.next:
return head
new_head = ListNode(0)
pre = new_head
while True:
count = k
stack = []
tmp = head
while count and tmp:
stack.append(tmp)
tmp = tmp.next
count -= 1
if count:
pre.next = head
break
while stack:
pre.next = stack.pop()
pre = pre.next
pre.next = tmp
head = tmp
return new_head.next