標籤:
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
這是一道hard的題目,但是其實思路並不複雜,做起來也比較有趣。做完Merge Two Sorted Lists再做這道題,很容易覺得修改Merge Two中的思路就可以再做這道題。Merge k 與Two主要的不同點在於Merge K一次最多需要比較K個結點,複雜度比較高,而且每次比完之後,移除最小的,加入新元素需要繼續比較,k-1個元素本身不變,很自然而然的想到使用堆來做。結合題目的需要,需要比較K個元素取得最小的元素,應該使用最小堆。python 中使用heapq這個模組。每次比較複雜度為O(logk).一共需要比較nk次,所以複雜度為nkO(logk)。空間複雜度為O(1)(堆的大小最大為k),代碼如下:
class Solution(object): def mergeKLists(self, lists): """ :type lists: List[ListNode] :rtype: ListNode """ if not lists: return None if len(lists) == 1: return lists[0] dummy = ListNode(-1) cur = dummy pq = [(n.val,n) for n in lists if n] heapq.heapify(pq) while pq: n = pq[0][1] if not n.next: heapq.heappop(pq) else: heapq.heapreplace(pq,(n.next.val,n.next)) cur.next = n cur = cur.next return dummy.next
需要注意的是,這裡heapq中存入的元素為結構元素,而不是直接的值,可以將每個結點使用tuple表示,元組中的第一個值為比較的索引值,否則會一直逾時。
這題還有另外一個思路,即二分,遞迴調用Merge Two Lists。即先將Lists兩兩合并,將合并的結果繼續兩兩合并。複雜度為:
2n*(k/2)+4n*(k/4)+8n*(k/8)+....=nklog(k).其中(k/2),(k/2)為每次合并的次數。具體代碼可以有遞迴和迭代兩種寫法。
Merge k Sorted Lists