LeetCode 148 排序連結串列
阿新 • • 發佈:2021-01-07
技術標籤:資料結構與演算法連結串列指標演算法leetcode資料結構
給你連結串列的頭結點head,請將其按 升序 排列並返回 排序後的連結串列 。
進階:
你可以在O(nlogn) 時間複雜度和常數級空間複雜度下,對連結串列進行排序嗎?
示例 1:
輸入:head = [4,2,1,3]
輸出:[1,2,3,4]
示例 2:
輸入:head = [-1,5,3,4,0]
輸出:[-1,0,3,4,5]
示例 3:
輸入:head = []
輸出:[]
提示:
連結串列中節點的數目在範圍[0, 5 * 104]內
-105<= Node.val <= 105
解題思路:
自頂向下歸併排序。
對連結串列自頂向下歸併排序的過程如下。
找到連結串列的中點,以中點為分界,將連結串列拆分成兩個子連結串列。尋找連結串列的中點可以使用快慢指標的做法,快指標每次移動 2步,慢指標每次移動 1步,當快指標到達連結串列末尾時,慢指標指向的連結串列節點即為連結串列的中點。
對兩個子連結串列分別排序。
將兩個排序後的子連結串列合併,得到完整的排序後的連結串列。可以使用「21. 合併兩個有序連結串列」的做法,將兩個有序的子連結串列進行合併。
上述過程可以通過遞迴實現。遞迴的終止條件是連結串列的節點個數小於或等於 1,即當連結串列為空或者連結串列只包含 1個節點時,不需要對連結串列進行拆分和排序。
Python程式碼:
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next class Solution: def sortList(self, head: ListNode) -> ListNode: if not head or not head.next: return head fast = head.next slow = head while fast and fast.next: fast = fast.next.next slow = slow.next mid = slow.next slow.next = None return self.mergeTwoLists(self.sortList(head), self.sortList(mid)) def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode: dummy = ListNode(-1) pre = dummy while l1 and l2: if l1.val <= l2.val: pre.next = l1 l1 = l1.next else: pre.next = l2 l2 = l2.next pre = pre.next if l1: pre.next = l1 else: pre.next = l2 return dummy.next