(python刷題)leetcode 第25題:K 個一組翻轉鏈表

題目描述
在這裏插入圖片描述
解題思路

  1. 將整個鏈表分爲已翻轉區,待翻轉區和未翻轉區三個部分
  2. 初始化一個虛擬節點dummy,待翻轉區的前驅節點pre和後繼節點end初始化爲pre=end=dummy
  3. 通過循環找到待翻轉區的範圍,每循環一次,end向前走一步,循環k次後end就位於待翻轉區的末尾節點,初始化start=pre.next就得到了待翻轉區的範圍[start, end]
  4. 記錄end的後一個節點next=end.next,以便翻轉後將這三個部分進行連接,然後將end.next=null才能對其進行翻轉操作
  5. 對待翻轉區進行翻轉,並使得pre指向翻轉後的新節點,此時start爲翻轉後的尾節點,將start指向next,使得與下一個部分進行連接
  6. 更新pre和end,pre=end=start
  7. 重複1-6直到整個鏈表處理完成
  8. 另外,需要注意的是,如果待翻轉區的長度小於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
                                
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章