在 o(n log n) 時間複雜度和常數級空間複雜度下,對鍊錶進行排序
示例 1:
輸入: 4->2->1->3
輸出: 1->2->3->4
示例 2:
輸入: -1->5->3->4->0
輸出: -1->0->3->4->5
題解題目要求時間空間複雜度分別為o(nlogn)
和o(1)
,根據時間複雜度我們自然想到二分法,從而聯想到歸併排序;
通過遞迴實現鍊錶歸併排序,有以下兩個環節:
分割 cut 環節: 找到當前鍊錶中點,並從中點將鍊錶斷開(以便在下次遞迴 cut 時,鍊錶片段擁有正確邊界);
我們使用fast
,slow
快慢雙指標法,奇數個節點找到中點,偶數個節點找到中心左邊的節點。
找到中點 slow 後,執行slow.next = none
將鍊錶切斷。
遞迴分割時,輸入當前鍊錶左端點head
和中心節點slow
的下乙個節點tmp
(因為鍊錶是從 slow 切斷的)。
cut 遞迴終止條件:當head.next == none時,說明只有乙個節點了,直接返回此節點
合併 merge 環節:將兩個排序鍊錶合併,轉化為乙個排序鍊錶。
雙指標法合併,建立輔助listnodeh
作為頭部。
設定兩指標 left, right 分別指向兩鍊錶頭部,比較兩指標處節點值大小,由小到大加入合併鍊錶頭部,指標交替前進,直至新增完兩個鍊錶。
返回輔助listnodeh
作為頭部的下個節點h.next
。
時間複雜度o(l + r)
,l
,r
分別代表兩個鍊錶長度
程式:
# definition for singly-linked list.
# class listnode:
# def __init__(self, x):
# self.val = x
# self.next = none
class
solution
:def
sortlist
(self, head: listnode)
-> listnode:
# 直接返回
ifnot head or
not head.
next
:return head
# 找中點
low, fast = head, head.
next
while fast and fast.
next
: low = low.
next
fast = fast.
next
.next
mid = low.
next
low.
next
=none
# 繼續遞迴拆分
left, right = self.sortlist(head)
, self.sortlist(mid)
# 兩兩合併
res = start = listnode(0)
while left and right:
if left.val < right.val:
start.
next
= left
start = start.
next
left = left.
next
else
: start.
next
= right
right = right.
next
start = start.
next
if left:
start.
next
= left
if right:
start.
next
= right
return res.
next
參考148. leetcode題解
data =[1
,3,2
,5,4
,6]def
merge
(left, right)
: result =
while left and right:
if left[0]
< right[0]
:0))
else:0
))if left:
result.extend(left)
if right:
result.extend(right)
return result
defsplit
(data):if
len(data)
<2:
return data
# 使用終點分割
mid =
len(data)//2
l, r= data[
:mid]
, data[mid:
]# 使用遞迴繼續分割
left, right = split(l)
, split(r)
# 分割成最小粒度後合併
res = merge(left, right)
return res
print
(split(data)
)
總結1,2兩題歸併排序的一般套路為:
分割,每次從中間分割,直到分割成只剩乙個數字時停止,這個過程可以使用遞迴實現
合併,將分割後的陣列進行合併,兩兩合併直到合併成原始陣列大小
時間複雜度為on的排序演算法 演算法的時間複雜度理論
yishun 可計算性理論的理解 zhuanlan.zhihu.com 現在,我們來討論演算法執行的時間複雜度。表示以下函式集合 o g n 表示以下函式集合 表示以下函式集合 f n 或 o g n 表示f n 是 或 o g n 的成員。首先要明確輸入規模的概念,一般來說,它指編碼演算法輸入所需...
時間複雜度為O(n)的排序演算法
我們常用的幾種排序演算法,氣泡排序,選擇排序,它們已經是相對比較簡單,穩定的排序演算法了,但是它們時間複雜度為o n n 基本都要用到兩層迴圈,今天我就像大家介紹一種簡單,只用一層for迴圈,時間複雜度為o n 的排序演算法。樣例輸入 1 4 5 6 3 4 2 8 9 1 樣例輸出 1 1 2 3...
演算法時間複雜度空間複雜度
演算法 是解決某一類問題的通法,即一系列清晰無歧義的計算指令。每個演算法只能解決具有特定特徵的一類問題,但乙個問題可由多個演算法解決。乙個演算法應該有以下五個方面的特性 比較演算法的優劣我們從兩個維度去進行考量 時間 空間 時間複雜度,空間複雜度 找出基本語句 演算法中執行次數最多的那條語句就是基本...