目錄
題目:
解法一:遞歸改變節點連接
思路:1.採用分治思想,從後往前遞歸,調用遞歸函數傳進去下一個k部分的頭結點和k,遞歸結束是節點爲空,此時count 不爲0,遞歸返回最後這部分(不管是否滿k個節點)的頭結點;
2.反轉操作是從後往前,倒數第二部分head指向最後一部分head(遞歸返回),依次在倒數第二部分進行k次反轉,return head(反轉後的head)
class Solution:
def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
if not head:
return
cur = head
count = k
while count and cur: # 循環結束,cur指向下一段Head;邊界情況(1,2,3,4,5,6),第二次調用函數傳入head=4,k=3,返回是cur=none,k=3,所以會有第三次調用函數
cur = cur.next
count -= 1
if count:
return head
next_head = self.reverseKGroup(cur, k)
while k:
third = head.next
head.next = next_head
next_head = head
head = third
k -= 1
return next_head
解法二:尾插法:
思路:1.從前往後,找到第k個節點tail,依次把第一個節點插入到tail後面;
2.再連接下一段,初始化head
class Solution:
def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
if not head:
return head
dummy = ListNode(0) # 鏈表變化後不好找head的可以定義一個dummy結點
dummy.next = head
tail = dummy.next
pre = dummy
while True:
count = k
while count > 1 and tail: # 找到第k個作爲tail
tail = tail.next
count -= 1
next_pre = pre.next # 沒反轉前的第一個節點爲反轉後的結束節點,即下一次循環時pre更新的位置
if not tail: break # 如果當前循環不存在tail,說明到達最後一部分不滿足k個節點
while pre.next != tail: # 當pre的下一個節點不爲tail,循環把pre的下一個節點移動到tail後面(移動一個節點到其他節點前或後)
cur = pre.next
pre.next = cur.next
cur.next = tail.next
tail.next = cur
pre = next_pre # 一個k部分的節點移動結束,初始化pre,tail
tail = pre.next
return dummy.next
解法三:使用輔助空間,這裏使用棧
思路:
1.從前往後遍歷k個節點先存入棧中,當最後一部分不滿足k個節點時,倒數第二部分尾節點指向,最後一部分頭結點
2.出棧依次連接,更新指針
class Solution:
def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
if not head:
return
dummy = ListNode(0)
dummy.next = head
cur = head
p = dummy
while True:
stack = []
while k and cur: # 跳出循環是,cur是第k+1個節點
stack.append(cur)
cur = cur.next
k -= 1
if k > 1:
p.next = cur # 最後一段不滿k個節點,則前一部分最後一個節點指向最後一部分的head節點
break
while stack:
p.next = stack.pop()
p = p.next
p.next = cur
return dummy.next
解法四:遞歸交換值,不改變鏈表連接
思路: 每k個部分使用left,right指針,交換值,來完成反轉
TODO:遞歸交換值,代碼滿足類似1,2,3,4,5 k=2,3; 但是不滿足1,2,3,4 k=4情況
class Solution:
def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
if not head:
return
if k == 1:
return head
def reverse_detailed(cur, k):
nonlocal stop, left, right
if k < 2 or not right:
return
right = right.next
if not right:
return
tail = reverse_detailed(right,k-1)
if not right:
return
if k == 2:
tail = right
if left == right or right.next == left:
stop = True
return tail
if not stop:
left.val, right.val = right.val, left.val
left = left.next
return tail
cur = head
while cur:
if not cur: # 循環更新了cur
return
stop = False
left = right = cur
tail = reverse_detailed(cur, k)
if tail:
cur = tail.next
else:
return head
return head