方法一:最容易想到的,就是暴力解法
先遍历所有的链表,将所有的结点的值放到一个列表中。
再将这个列表排序。
再把列表里的值重新构建成一个链表
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
def generateList(l: list):
prenode = ListNode(0)
lastnode = prenode
for val in l:
lastnode.next = ListNode(val)
lastnode = lastnode.next
return prenode.next
def printList(l: ListNode):
while l:
print("%d, " % (l.val), end='')
l = l.next
def mergeKLists(lists):
nodes = []
head = point = ListNode(0)
for l in lists:
while l:
nodes.append(l.val)
l = l.next
for x in sorted(nodes): #sorted从小到大排列
point.next = ListNode(x)
point = point.next
return head.next
l1 = generateList([1, 5, 8])
l2 = generateList([9, 1, 2, 9])
lists = [l1,l2]
result = mergeKLists(lists)
printList(result) #1, 1, 2, 5, 8, 9, 9,
复杂度分析:
时间复杂度:O(NlogN)
1.N个结点的总个数。遍历所有结点需要花费O(N)时间
2.一个稳定的排序算法大概要花费O(NlogN)时间
3.重新构建链表需要花费O(N)时间
法二:采用分治思想
从K条有序链表中,选取两条两条地合并,最终合并成一条。
首先是两条链表合并的代码:(递归)
def mergeTwoLists(l1, l2):
if not l1:return l2
if not l2:return l1
if l1.val < l2.val:
l1.next = self.mergeTwoLists(l1.next, l2)
return l1
else:
l2.next = self.mergeTwoLists(l1, l2.next)
return l2
接着是,怎么选择两条链表的代码:(用二分法的思路选择两条相邻的链表进行合并)
def merge(lists, left, right):
if left == right:
return lists[left]
mid = left + (right - left) // 2
l1 = self.merge(lists, left, mid)
l2 = self.merge(lists, mid+1, right)
return self.mergeTwoLists(l1, l2)
如下图,五个正方形代表五条 需要进行合并的有序链表,二分法会帮助我们先找到相邻的链表进行合并,再一层层达到合并全部链表的目的。
总的代码:
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
def generateList(l: list):
prenode = ListNode(0)
lastnode = prenode
for val in l:
lastnode.next = ListNode(val)
lastnode = lastnode.next
return prenode.next
def printList(l: ListNode):
while l:
print("%d, " % (l.val), end='')
l = l.next
def mergeKLists(lists: list) -> ListNode:
if not lists: return None
n = len(lists)
return merge(lists, 0, n - 1)
def merge(lists, left, right):
if left == right:
return lists[left]
mid = left + (right - left) // 2
l1 = merge(lists, left, mid)
l2 = merge(lists, mid + 1, right)
return mergeTwoLists(l1, l2)
def mergeTwoLists(l1, l2):
if not l1: return l2
if not l2: return l1
if l1.val < l2.val:
l1.next = mergeTwoLists(l1.next, l2)
return l1
else:
l2.next = mergeTwoLists(l1, l2.next)
return l2
l1 = generateList([1, 5, 6])
l2 = generateList([2,3,4,8])
l3 = generateList([0,1,6,8])
lists = [l1,l2,l3]
result = mergeKLists(lists)
printList(result) #0, 1, 1, 2, 3, 4, 5, 6, 6, 8, 8,