[Leetcode]Merge k Sorted Lists

19 篇文章 0 订阅
1 篇文章 0 订阅

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值