题目描述
解题思路
- 将整个链表分为已翻转区,待翻转区和未翻转区三个部分
- 初始化一个虚拟节点dummy,待翻转区的前驱节点pre和后继节点end初始化为pre=end=dummy
- 通过循环找到待翻转区的范围,每循环一次,end向前走一步,循环k次后end就位于待翻转区的末尾节点,初始化start=pre.next就得到了待翻转区的范围[start, end]
- 记录end的后一个节点next=end.next,以便翻转后将这三个部分进行连接,然后将end.next=null才能对其进行翻转操作
- 对待翻转区进行翻转,并使得pre指向翻转后的新节点,此时start为翻转后的尾节点,将start指向next,使得与下一个部分进行连接
- 更新pre和end,pre=end=start
- 重复1-6直到整个链表处理完成
- 另外,需要注意的是,如果待翻转区的长度小于k,那么则不翻转
为了更好的理解真个算法的过程,这里引用了 这篇博文的图
复杂度分析:
由于每次寻找待翻转区的范围需要循环k次,然后对待范围区翻转也需要遍历一次待翻转区,因此算法的时间复杂度为o(2n),即o(n)
由于即需要创建常数个变量,所以空间复杂度为o(1)
python代码
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def reverseKGroup(self, head, k):
"""
:type head: ListNode
:type k: int
:rtype: ListNode
"""
dummy = ListNode(0)
dummy.next = head
pre = end = dummy
while end.next:
for i in range(0, k):
if end:
end = end.next
else:
break
if end:
end_next = end.next
else:
break
start = pre.next
end.next = None
pre.next = self.reverseList(start)
start.next = end_next
pre = end = start
return dummy.next
def reverseList(self, head):
pre = None
cur = head
while cur:
cur_next = cur.next
cur.next = pre
pre = cur
cur = cur_next
return pre