Leetcode演算法——25、連結串列分組反轉
阿新 • • 發佈:2018-12-17
給定一個連結串列,每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())