题目描述:
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序
示例:
1) 输入:head = [1,2,3,4,5], k = 2
输出:[2,1,4,3,5]
2) 输入:head = [1,2,3,4,5], k = 3
输出:[3,2,1,4,5]
3) 输入:head = [1,2,3,4,5], k = 1
输出:[1,2,3,4,5]
4) 输入:head = [1], k = 1
输出:[1]
思路:
因为是K个一组翻转,先判断是否有K个,如果有进行对这K个翻转,翻转的思想与之前翻转链表或者说两两变换那里是相似的,需要注意的是,翻转一组后,这组的结点与前后的连接处理部分,需要细节一点。此外,还有一点需要注意的就是,需要返回链表的头,因为不断翻转,所以选择一个哨兵结点的方式,生成一个新的结点,他的next就指向头,不管后面怎么翻转他的next都是头,具体的处理详见代码,这里需要注意哨兵结点的使用!!!
class Solution(object):
def reverseKGroup(self, head, k):
"""
:type head: ListNode
:type k: int
:rtype: ListNode
"""
h = head
pre = self
pre.next = head
while self.test(h, k):
# 有k个进行交换
# print("进入第一次循环")
a = pre.next
b = a.next
fl = h
for i in range(k - 1):
c = b.next
b.next = a
a = b
b = c
pre.next.next = b
pre.next = a
h = b
pre = fl
return self.next
def test(self, h, k):
for i in range(k):
if h is None:
return False
elif i != k-1:
h = h.next
return True
哨兵结点这里还可以写成:
# class ListNode(object):
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution(object):
def reverseKGroup(self, head, k):
"""
:type head: ListNode
:type k: int
:rtype: ListNode
"""
h = head
hair = ListNode(-100) # 注意hair为哨兵结点,但是还需要一个pre进行拷贝,这样来完成循环翻转
hair.next = head
pre = hair
# pre = self # 这里的self相当于一个哨兵结点,也可以生成一个listnode来完成
# pre.next = head
while self.test(h, k):
# 有k个进行交换
a = pre.next
b = a.next
fl = h # h为这次的最后一个,相当于下一组的前一个结点
for i in range(k - 1): # 进行一段的转换
c = b.next
b.next = a
a = b
b = c
pre.next.next = b
pre.next = a
h = b
pre = fl
return hair.next
def test(self, h, k):
for i in range(k):
if h is None:
return False
elif i != k-1:
h = h.next
return True
时间复杂性为O(n), 空间复杂度为O(1)。
我写的代码,将是否有K个作为一个单独的函数,也可以将翻转作为一个单独的函数,官网的代码就是这个形式,如下:
class Solution:
# 翻转一个子链表,并且返回新的头与尾
def reverse(self, head: ListNode, tail: ListNode):
prev = tail.next
p = head
while prev != tail:
nex = p.next
p.next = prev
prev = p
p = nex
return tail, head
def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
hair = ListNode(0) # 哨兵结点
hair.next = head
pre = hair
while head:
tail = pre
# 查看剩余部分长度是否大于等于 k
for i in range(k):
tail = tail.next
if not tail:
return hair.next
nex = tail.next
head, tail = self.reverse(head, tail)
# 把子链表重新接回原链表
pre.next = head
tail.next = nex
pre = tail
head = tail.next
return hair.next