Merge k Sorted Lists

2017-07-29  本文已影响0人  穿越那片海

hard, linked list

Question

将k个有序链列合并为一个有序链列,注意分析算法复杂度

Solution

最直观最粗暴的方法是一个一个的比较,就可以使用Merge Two sorted list 合并有序数列来解决问题。假设每个链列有n个节点,第一次融合最糟糕需要比较2n次,第二次最糟糕需要2n+n次,。。。,总的需要2n+3n+...+kn=O(kn**2)

使用堆栈,将各个list的最小的数放入堆栈筛选,每个数的cost是log(k),一个nk个数,所以time complexity是nklog(k), 因为额外的堆栈,space complexity是O(k)

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def mergeKLists(self, lists):
        """
        :type lists: List[ListNode]
        :rtype: ListNode
        """
        from heapq import heappush, heappop, heapreplace, heapify
        dummy =  ListNode(0)
        node = dummy
        h = [(n.val, n) for n in lists if n]
        heapify(h)
        while h:
            v, n = h[0]
            if n.next is None:
                heappop(h) #only change heap size when necessary
            else:
                heapreplace(h, (n.next.val, n.next))
            node.next = n
            node = node.next
            
        return dummy.next

另外一个方法借助Queue() package

from Queue import PriorityQueue
class Solution(object):
    def mergeKLists(self, lists):
        dummy = ListNode(None)
        curr = dummy
        q = PriorityQueue()
        for node in lists:
            if node: q.put((node.val,node))
        while q.qsize()>0:
            curr.next = q.get()[1]
            curr=curr.next
            if curr.next: q.put((curr.next.val, curr.next))
        return dummy.next

也可以借助Merge Two sorted list 合并有序数列但是使用divide and conquer的办法

def mergeKLists(self, lists):
    if not lists:
        return None

    while len(lists) > 1:
        merged = []
        while len(lists) > 1:
            merged.append(self.merge(lists.pop(), lists.pop()))
        lists += merged
    return lists[0]
    
def merge(self, x, y, s):
    dummyHead = ListNode(0)
    p = dummyHead
    while x and y:
        if x.val < y.val:
            p.next = x
            x = x.next
        else:
            p.next = y
            y = y.next
        p = p.next
    p.next = x if x else y
    return dummyHead.next
上一篇下一篇

猜你喜欢

热点阅读