23. 合并K个排序链表!

合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。

示例:

输入:
[
  1->4->5,
  1->3->4,
  2->6
]
输出: 1->1->2->3->4->4->5->6

困难
【分析】逐一两两合并:((list[0]+list[1])+list[2])+...

# 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
        """
        if len(lists)==0:
            return None
        res=lists.pop(0)
        while len(lists)>0:
            res=self.merge2Lst(res,lists.pop(0))            
        return res
    
    def merge2Lst(self,head1,head2):
        res=ListNode(0)
        node=res
        while head1 and head2:
            if head1.val>head2.val:
                node.next=ListNode(head2.val)
                head2=head2.next
            else:
                node.next=ListNode(head1.val)
                head1=head1.next
            node=node.next  
        node.next=head1 if head1 else head2
        return res.next
        

时间超出限制,时间复杂度是 O ( k N ) O(kN) O(kN).

【分析】分治法:两两合并。(list[0]+list[1])+(list[2]+list[3])+...

# 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
        """
        if len(lists)==0:
            return None
        while len(lists)>1:
            lists.append(self.merge2Lst(lists.pop(0),lists.pop(0)))       
        return lists[0]
    
    def merge2Lst(self,head1,head2):
        res=ListNode(0)
        node=res
        while head1 and head2:
            if head1.val>head2.val:
                node.next=ListNode(head2.val)
                head2=head2.next
            else:
                node.next=ListNode(head1.val)
                head1=head1.next
            node=node.next  
        node.next=head1 if head1 else head2
        return res.next

时间复杂付 O ( N l o g k ) O(Nlogk) O(Nlogk)
【分析】利用优先队列:最高优先级的先出来。举个栗子
lists= [
0->4->5,
1->3->4,
2->6
]

  • 利用优先队列取出list[0],list[1],…,list[k-1]中的头节点,加入到优先队列中。栗子中是0,1,2被拿出来放到了优先队列里面。
  • 然后在优先队列中,弹出最小的那个放到答案中,同时这个将弹出来的这个节点的next又加入优先队列。栗子中,0会被答案征用,然后4会被拿出来放到优先队列里,此时优先队列(按照先进先出原则和优先级的原则)的值为1,2,4。

通俗一点,也就是说,只要这k个链表还有节点弹出来,那么每次就会比较这k个节点的val(通过优先队列实现,时间更短,而不是单纯的比较),有哪个链表的节点被答案征用了,那么这个链表就会从再次弹出节点来与其他链表的头节点来做比较,直到所有链表的头节点都被比较完为止。

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

from Queue import PriorityQueue
class Solution(object):
    def mergeKLists(self, lists):
        res=ListNode(0)
        node=res
        p_queue=PriorityQueue()
        for head in lists:
            if head:
                p_queue.put((head.val,head))
        while not p_queue.empty():
            val,head=p_queue.get()
            node.next=ListNode(val)
            if head.next:
                p_queue.put((head.next.val,head.next))
            node=node.next
        return res.next

注: python的优先队列是值小的先出来,如果要限制它从大到小出来,可以乘以-1.

注:测试用例。

#    输入:
#    [
#      1->4->5,
#      1->3->4,
#      2->6
#    ]
#    输出: 1->1->2->3->4->4->5->6 

##生成节点
def createListNode(lst):
    head=ListNode(lst.pop(0))
    node=head
    while lst:
        node.next=ListNode(lst.pop(0))
        node=node.next
    return head

l1,l2,l3=[1,4,5],[1,3,4],[2,6]
lists=[createListNode(l1),createListNode(l2),createListNode(l3)]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值