題目描述
解題思路
- 將整個鏈表分爲已翻轉區,待翻轉區和未翻轉區三個部分
- 初始化一個虛擬節點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