1. 程式人生 > >Leetcode篇:k個一組翻轉連結串列

Leetcode篇:k個一組翻轉連結串列


@author: ZZQ
@software: PyCharm
@file: ReverseList.py
@time: 2018/11/6 15:13
題目要求:給出一個連結串列,每 k 個節點一組進行翻轉,並返回翻轉後的連結串列。
k 是一個正整數,它的值小於或等於連結串列的長度。如果節點總數不是 k 的整數倍,那麼將最後剩餘節點保持原有順序。
示例 :
給定這個連結串列:1->2->3->4->5
當 k = 2 時,應當返回: 2->1->4->3->5
當 k = 3 時,應當返回: 3->2->1->4->5
說明 :
你的演算法只能使用常數的額外空間。
你不能只是單純的改變節點內部的值,而是需要實際的進行節點交換。
思路:針對每個子連結串列進行反轉,需要在每次做翻轉時記錄當前子連結串列的首節點,尾節點以及下一個待翻轉連結串列的首節點。
需要注意當剩餘節點數小於k的情況以及連結串列本身為空的情況。

class ListNode(object):
    def __init__(self, x):
        self.val = x
        self.next = None


class Solution():
    def __init__(self):
        pass

    def reverseKGroup(self, head, k):
        """
        :type head: ListNode
        :type k: int
        :rtype: ListNode
        """

        if k == 0 or k == 1 or head is None or head.next is None:
            return head

        NextListHeadNode = head
        NewH = ListNode(0)
        tempNewH = ListNode(0)
        time = 0
        while head.next is not None and tempNewH is not None:
            if time == 0:
                count, PreListFirstNode, PreListLastNode, NextListHeadNode = self.ReverseKList(head, k)
                time += 1
                NewH = PreListFirstNode
                PreListLastNode.next = NextListHeadNode
                tempNewH = NewH
                if count < k:
                    for i in range(count):
                        tempNewH = tempNewH.next
                else:
                    for i in range(count - 1):
                        tempNewH = tempNewH.next
            else:
                head = NextListHeadNode
                count, PreListFirstNode, PreListLastNode, NextListHeadNode = self.ReverseKList(head, k)
                PreListLastNode.next = NextListHeadNode
                tempNewH.next = PreListFirstNode
                time += 1
                tempNewH = tempNewH
                if count < k:
                    for i in range(count+1):
                        tempNewH = tempNewH.next
                else:
                    for i in range(count):
                        tempNewH = tempNewH.next

        return NewH

    def ReverseKList(self, head, k):

        PreH = ListNode(0)
        PostH = head.next
        count = 0
        while head is not None and count < k:
                head.next = PreH
                PreH = head
                head = PostH
                if PostH is not None:
                    PostH = PostH.next
                count += 1
        if head is None and count < k:  # 如果剩餘的節點個數小於k,則返回原來的節點順序
            lastFirstNode = self.ReverselastList(PreH)
            lastEndnode = lastFirstNode
            for i in range(count-1):
                lastEndnode = lastEndnode.next
            lastEndnode.next = None
            return count, lastFirstNode, lastEndnode, None
        else:
            tempPreH = PreH
            tt = count
            while tt-1 > 0:
                tempPreH = tempPreH.next
                tt -= 1
            return count, PreH, tempPreH, head
        # 返回當前子連結串列經過翻轉後的首節點,尾節點以及下一個子連結串列未反轉前的首節點

    def ReverselastList(self, head):
        PreH = ListNode(0)
        PostH = head.next
        while head is not None:
                head.next = PreH
                PreH = head
                head = PostH
                if PostH is not None:
                    PostH = PostH.next
        return PreH.next