Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
合并k个有序的链表~
brute force的方法是把这k个链表一个一个的合并起来,如 k个链表为[l1, l2, l3, l4],可以先合并l1, l2,再把合并得到的链表与l3合并,最后再与l4合并,两个链表合并的解法可以参考Merge Two Sorted Lists~关于时间复杂度,这儿要进行k - 1次合并,l1与l2合并时最坏的情况是要进行n + n = 2n次的比较~ 再与l3进行合并时最坏的情况是要进行2n + n = 3n次的比较,所以总共要进行的比较次数是2n + 3n + 4n + ... + kn = O(nk^2).因此时间复杂度就为O(nk^2)~
还可以用heap来做~可以维护一个大小为k的最小堆~每次把堆顶的最小结点放到结果链表中,然后把该结点的下一个元素push到heap中,并维护heap的结构~因为每个元素要读取一次,也就是k*n次,然后每次读取完元素后后要把该元素的下一个结点插入堆中,这个步骤需要logk的复杂度,所以总时间复杂度是O(nklogk)~空间复杂度为堆的大小O(k)~ 代码如下~
class Solution:
# @param a list of ListNode
# @return a ListNode
def mergeKLists(self, lists):
if lists is None or len(lists) == 0: return None
heap = []
dummy = ListNode(0)
curr = dummy
for node in lists:
if node:
heapq.heappush(heap, (node.val, node))
while heap:
node = heapq.heappop(heap)[1]
curr.next = node
curr = curr.next
if node.next:
heapq.heappush(heap, (node.next.val, node.next))
return dummy.next
还有一种解法:divide and conquer~ 先把k个list分成两半,然后继续划分,直到剩下两个list就合并起来(同样用merge two sorted lists的方法合并)~这种解法的时间复杂度同样为O(nklogk)~代码如下~
class Solution:
# @param a list of ListNode
# @return a ListNode
def mergeKLists(self, lists):
if lists is None or len(lists) == 0: return None
return self.helper(lists, 0, len(lists) - 1)
def helper(self, lists, l, r):
if l < r:
m = l + (r - l) / 2
return self.merge(self.helper(lists, l, m), self.helper(lists, m + 1, r))
return lists[l]
def merge(self, l1, l2):
if l1 is None: return l2
if l2 is None: return l1
newHead = ListNode(0)
currHead = newHead
while l1 and l2:
if l1.val <= l2.val:
currHead.next = l1
l1 = l1.next
else:
<span style="white-space:pre"> </span>currHead.next = l2
<span style="white-space:pre"> </span>l2 = l2.next
currHead = currHead.next
if l1:
currHead.next = l1
if l2:
currHead.next = l2
return newHead.next