1. 程式人生 > >重排連結串列

重排連結串列

題目描述:給定一個單鏈表L: L0→L1→…→Ln-1→Ln, 重新排列後為:L0→Ln→L1→Ln-1→L2→Ln-2→…必須在不改變節點值的情況下進行原地操作

樣例:給出連結串列1->2->3->4->null,重新排列後為1->4->2->3->null。

將L0,L1; L1,Ln-1;...排在一起,其實和迴文連結串列(詳見:點選開啟連結)的邏輯是一樣的,不同的是,迴文連結串列是比較值,這裡是通過“摘鏈”和“連結”的方法調整位置。

那思路就比較清楚了:和迴文連結串列的做法一致,首先,通過“快慢指標法”(詳見:點選開啟連結)找到中間節點,將中間節點之後的部分翻轉(也就是單鏈表逆置,詳見:

點選開啟連結),最後,依次將被逆置部分的連結串列的節點插入相應位置。

其實還是以前的東西,不過綜合在一起罷了。

那麼程式碼並不難:

"""
Definition of ListNode
class ListNode(object):

    def __init__(self, val, next=None):
        self.val = val
        self.next = next
"""
class Solution:
    """
    @param head: The first node of the linked list.
    @return: nothing
    """
    def reorderList(self, head):
        if head is None or head.next is None:
            return head
        slow, fast = head, head.next
        # 找到中間節點
        while fast and fast.next:
            fast = fast.next.next
            slow = slow.next
        # 以中間節點為界,將連結串列斷開,分成前後兩部分
        # 斷開的目的是方便連結串列翻轉操作
        cur = slow.next
        slow.next = None
        # 單鏈表逆置
        while cur:
            temp = cur
            cur = cur.next
            temp.next = slow.next
            slow.next = temp
        # 再次斷開成兩個連結串列,合併
        second = slow.next
        slow.next = None
        pre = head
        while second:
            temp = second
            second = second.next
            temp.next = pre.next
            pre.next = temp
            pre = temp.next
        return head
        # write your code here
需要注意的是,兩次將連結串列斷開都是為了方便對節點的操作。第一次是方便了單鏈表逆置,第二次是方便了連結串列合併。這種先斷開,再連結的方法我們之前用過很多了。