Merge k Sorted Lists
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)为每次合并的次数。具体代码可以有递归和迭代两种写法。
class Solution(object): def mergeKLists(self, lists): """ :type lists: List[ListNode] :rtype: ListNode """ if not lists: return None pq = [] for i in xrange(len(lists)): cur = lists[i] if cur: heapq.heappush(pq,(cur.val,cur)) pre = dummy = ListNode(-1) while pq: cur = heapq.heappop(pq)[1] pre.next = cur pre = pre.next cur = cur.next if cur: heapq.heappush(pq,(cur.val,cur)) return dummy.next
posted on 2016-04-24 16:36 Sheryl Wang 阅读(156) 评论(0) 编辑 收藏 举报