合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
解题思路
对于多路归并排列,我们可以使用优先队列解决。我们首先想到的解法是,依次将list
中的ListNode
弹出,然后一次添加到一个优先队列中,最后将优先队列中ListNode
依次弹出,并且添加到result中即可。
class Solution(object):
def mergeKLists(self, lists):
"""
:type lists: List[ListNode]
:rtype: ListNode
"""
import heapq
result = ListNode(-1)
cur = result
p = list()
for i in lists:
while i:
heapq.heappush(p, (i.val, i))
i = i.next
while p:
cur.next = heapq.heappop(p)[1]
cur = cur.next
return result.next
要注意的是上述写法只可以在python2
下使用,在python3
中会出现错误
TypeError: unorderable types: ListNode() < ListNode()
为什么呢?
当对一个tuple排序时,python会从0开始对两个tuple的成员依次比较,如果两个成员相同就再比较下一个成员。问题中的tuple很有趣,前两个链表的第一项比较结果都相同(1),于是python开始比较第二个成员,第二个成员是一个
ListNode
,没有比较方法,在处理这个问题上py2和py3有了差异,py2随机瞎排,py3则是抛出异常。
一种解决办法是我们重写一个ListNode
,给他添加__lt__
方法。我这里使用了另外的一种解决思路,就是在tuple
中再添加一个元素。( ̄▽ ̄)”
class Solution(object):
def mergeKLists(self, lists):
"""
:type lists: List[ListNode]
:rtype: ListNode
"""
import heapq
result = ListNode(-1)
cur = result
p = list()
x = 0
for i in lists:
while i:
heapq.heappush(p, (i.val, x, i))
i = i.next
x += 1
while p:
cur.next = heapq.heappop(p)[1]
cur = cur.next
return result.next
另外我们也可以这样做。
首先将list
中的每个链表
比较首元素,然后依次加入优先队列(或者一个堆,我这里使用堆)
q : 1 1 2
| | |
4 3 6
| |
5 4
然后判断这个优先队列
是否为空,不为空,我们弹出队首元素(1
),接着判断这个弹出的元素作为一个链表节点,其后是否还有元素,如果有元素,将元素加入队列。同时将结果加入到result
中
q : 1 2 4
| | |
3 6 5
|
4
result: 1
接着我们通过这个思路写出如下代码
class Solution(object):
def mergeKLists(self, lists):
"""
:type lists: List[ListNode]
:rtype: ListNode
"""
import heapq
result = ListNode(-1)
cur = result
p = list()
for i in lists:
if i:
heapq.heappush(p, (i.val, i))
while len(p) > 0:
cur.next = heapq.heappop(p)[1]
cur = cur.next
if cur.next:
heapq.heappush(p, (cur.next.val, cur.next))
return result.next
这里的代码同样会出现第一种情况下的问题,所以也可以按照之前的解决方法解决这个问题。
当然你可以先将所有元素加入到一个普通的队列中,然后通过sorted(list, key=lambda x : x.val)
排序,对这个排好序的list
,我们还要将它串成一个链表。
我将该问题的其他语言版本添加到了我的GitHub Leetcode
如有问题,希望大家指出!!!