leetcode 23 合併K個排序鍊錶

2021-09-12 07:04:27 字數 1631 閱讀 3939

合併 k 個排序鍊錶,返回合併後的排序鍊錶。請分析和描述演算法的複雜度。

示例:

輸入:

[  1->4->5,

1->3->4,

2->6

]輸出: 1->1->2->3->4->4->5->6

分析:

我想是k次歸併。時間複雜度是(k-1)nlogn。

題目分析:本題首先將每個鍊錶的首元素取出,構建乙個最小堆。堆頂則為最小的元素,用最小元素所在的那個鍊錶的第二個元素替換掉它的位置。然後維護最小堆的特性,再取出堆頂元素,……,一直到所有鍊錶元素都取出為止。

時間複雜度分析:一共是k個鍊錶,假設每個鍊錶有n個元素,首先是k個鍊錶首元素的建堆,花費o(k),然後取堆頂元素,用下乙個元素替換掉它,維護最小堆的特性,花費o(lgk),共有k*n個元素,所以花費(k*n-1)*lgk的時間,故總時間為o(k*n*lgk)

我們用優先佇列來實現,優先佇列的底層是用堆實現的。所謂優先,指的是佇列裡的元素按照優先順序大小排列,優先順序大的排在前面,優先順序相同的按照入隊的順序排列。首先將每個鍊錶的首元素入隊,將最小元素置於堆頂,然後找最小元素所在鍊錶的下乙個元素入隊,一直到隊為空。

from queue import priorityqueue

class solution(object):

def mergeklists(self, lists):

dummy = curr = listnode(none)

q = priorityqueue()

for idx,node in enumerate(lists):

# 我的媽,鍊錶竟然可以這樣遍歷

# print(idx,node) # typeerror: 'listnode' object is not iterable

# 不可以這樣遍歷- -

if node:

q.put((node.val,idx,node))

# print(q.get()) # (1, 0, <__main__.listnode object at 0x105d20518>)

while not q.empty():

# 最小的元素在鍊錶尾部

_,idx,curr.next = q.get()

curr = curr.next

if curr.next:q.put((curr.next.val,idx,curr.next))

return dummy.next

## using minheap

def mergeklists2(self, lists):

dummy = curr = listnode(none)

heap =

for idx, node in enumerate(lists):

if node:

while heap:

curr = curr.next

if curr.next:

return dummy.next

詳細用法:python堆和優先佇列的使用

參考: 

原文:

分治實現LeetCode 23題 合併K個排序鍊錶

紀念第一道沒有看題解做出來的困難題 分治思想 歸併排序實現合併k個排序鍊錶 由於是實現一連串已經排序的鍊錶,所以第一時間想到了歸併排序 又由於是實現多個鍊錶的總排序,為了減少時間複雜度又想到了分治思想,這一題中也就是二分法 做了這麼多天的題總算有點進步 class solution 結果陣列的頭結點...

LeetCode 23 合併 K個排序序列

合併 k 個排序鍊錶,返回合併後的排序鍊錶。請分析和描述演算法的複雜度。示例 輸入 1 4 5,1 3 4,2 6 輸出 1 1 2 3 4 4 5 6 解題思路 採用分治的思想,將 k 個鍊錶的合併問題轉換成,合併 2 個有序鍊錶的問題 typedef struct listnode list 定...

Leetcode23 合併K個排序鍊錶

題目 解題思路 這道題使用的是分治演算法。首先還用輔助函式mergetwolists 用來合併兩個有序單鏈表,不申請額外的空間實現原地合併。如下 listnode mergetwolists listnode l1,listnode l2 else head nexthead while l1 nu...