1. 程式人生 > >Leetcode演算法——25、連結串列分組反轉

Leetcode演算法——25、連結串列分組反轉

給定一個連結串列,每k個節點一組進行組內反轉,返回修改後的連結串列。

其中: 1、k是一個正數,且小於等於列表的長度。 2、如果節點數不是k的整數倍,則最後剩餘的節點需要保持原樣。 3、只能使用常量的記憶體。 4、不能改變節點的值,只能修改節點本身。

示例:

輸入: 1->2->3->4->5
如果 k = 2, 則輸出: 2->1->4->3->5
如果 k = 3, 則輸出: 3->2->1->4->5

思路

首先,需要知道組內反轉是如何操作的。

給出一個連結串列,p1 -> p2 -> p3,如果想將整個連結串列反轉,操作如下:

  • 在前面新增一個指標,得到 p0 -> p1 -> p2 -> p3
  • 開始從頭指標開始掃描,每次掃描時,先將當前節點的下一個節點暫存起來,記為 store,然後將當前節點指向上一個節點,然後繼續處理 store 這個節點。直至 store 為空。

接下來,便可以先進行分組,再進行組內反轉。

分組可以使用遞迴法來操作:只要剩餘連結串列長度大於等於k,則將前k個進行反轉,然後繼續遞迴處理剩下的連結串列。

python實現

class ListNode:
    def __init__(self, x):
        
        if isinstance(x, list
): self.val = x[0] self.next = None head = self for i in range(1, len(x)): head.next = ListNode(x[i]) head = head.next else: self.val = x self.next = None def output(self): ''' 輸出連結串列 '''
result = str(self.val) head = self.next while(head is not None): result += f' -> {head.val}' head = head.next return '(' + result + ')' def reverseKGroup(head, k): """ :type head: ListNode :type k: int :rtype: ListNode 遞迴,只要剩餘連結串列長度大於等於k,則將前k個進行反轉,然後繼續處理剩下的連結串列。 """ def fun_rec(p): ''' :type p: ListNode 從連結串列p的下一位開始,每k個一組進行組內反轉。 ''' # 連結串列長度是否大於等於k p0 = p c = 0 while(c < k and p.next): p = p.next c += 1 if c < k: return p pe = p # 將第k個儲存起來 pe2 = pe.next # 將第k+1個儲存起來 p1 = p0.next # 將第1個儲存起來,作為下一次遞迴的引數 p0.next = pe # 首指標指向第k個 # 開始迴圈反轉前k個連結串列 c = 0 p = p1 next = pe2 while(c < k): p_next = p.next p.next = next next = p p = p_next c += 1 fun_rec(p1) # 繼續處理剩下的連結串列 if k == 1 or not head: return head head0 = ListNode(0) head0.next = head fun_rec(head0) return head0.next if '__main__' == __name__: head = ListNode([1,2,3,4,5]) k = 2 print(reverseKGroup(head, k).output())