题目链接:
力扣https://leetcode-cn.com/problems/merge-k-sorted-lists/
【方法一 自定义排序】看到这个数据量,组多5*10^6,于是先遍历所有点,放在一个数组中,再根据val排序后,从前向后串起来即可。
# Definition for singly-linked list.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def mergeKLists(self, lists) -> ListNode:
arr = []
for node in lists:
p = node
while p:
arr.append(p)
p = p.next
arr.sort(key=lambda x: x.val)
for i in range(len(arr) - 1):
arr[i].next = arr[i + 1]
arr[-1].next = None
【方法二 分治法 两两合并】如图所示,把list两两分组,按两条的方式合并,再把合并后的新链表两两合并,直到只剩一条。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def merge(self, p, q):
start = ListNode()
cur = start
while p != None and q!= None:
if p.val < q.val:
cur.next = p
p = p.next
else:
cur.next = q
q = q.next
cur = cur.next
if p != None:
cur.next = p
if q != None:
cur.next = q
return start.next
def mergeKLists(self, lists) -> ListNode:
if len(lists) == 0:
return None
while len(lists) != 1:
next = []
i, n = 0, len(lists)
while True:
if i + 1 < n:
next.append(self.merge(lists[i], lists[i + 1]))
else:
next.append(lists[i])
i += 2
if i >= n:
break
lists = next
return lists[0]
【方法三 优先队列】利用优先队列把两两合并改成多个一起合并,思路就是先把每一条链的头节点放进优先队列,那么就已经排好顺序了,接下来每次取出最小的,再把取出来节点的next压入优先队列即可。
# Definition for singly-linked list.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def mergeKLists(self, lists) -> ListNode:
import heapq
priority_queue = []
for i in range(len(lists)):
if lists[i]:
heapq.heappush(priority_queue, (lists[i].val, i))
start = ListNode()
cur = start
while priority_queue != []:
top = heapq.heappop(priority_queue)
node = lists[top[1]]
cur.next = node
if node.next:
heapq.heappush(priority_queue, (node.next.val, top[1]))
lists[top[1]] = node.next
cur = cur.next
return start.next