【leedcode.25:Reverse Nodes in k-Group】 每k個節點反轉_遞歸非遞歸4種解法

目錄

 

題目:

解法一:遞歸改變節點連接

解法二:尾插法:

解法三:使用輔助空間,這裏使用棧

解法四:遞歸交換值,不改變鏈表連接


題目:

 

解法一:遞歸改變節點連接

           思: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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章