题目描述
解题思路
解法一:暴力法
- 遍历k个链表,将所有节点值保存到列表中
- 将列表排序
- 遍历排序后的列表,创建一个新的有序链表
python代码
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
self.nodes = []
tmp = head = ListNode(0)
for i in lists:
while i:
self.nodes.append(i.val)
i = i.next
for j in sorted(self.nodes):
head.next = ListNode(j)
head = head.next
return tmp.next
运行结果
时间复杂度:,其中 是节点的总数目。
- 遍历所有的值需花费 的时间。
- 一个稳定的排序算法花费 的时间。
- 遍历同时创建新的有序链表花费 的时间。
空间复杂度: 。
- 排序花费 空间(这取决于你选择的算法)。
- 创建一个新的链表花费 的空间。
解法二:分治算法
分治其实就是不断缩小其规模,再不断合并扩大的过程
找到中间点,将其一分为二,再不停的进行拆分,直至到不能再拆分(规模为1的时候)便返回。
之后开始合并,合并的代码借用了合并两个排序链表的代码。
当两个规模最小的链表合并完后,其规模就变大了,然后不断重复这个合并过程,直到最终得到一个有序的链表。
python代码
amount = len(lists)
interval = 1
while interval < amount:
for i in range(0, amount - interval, interval * 2):
lists[i] = self.merge2Lists(lists[i], lists[i + interval])
interval *= 2
return lists[0] if amount > 0 else lists
def merge2Lists(self, l1, l2):
head = point = ListNode(0)
while l1 and l2:
if l1.val <= l2.val:
point.next = l1
l1 = l1.next
else:
point.next = l2
l2 = l1
l1 = point.next.next
point = point.next
if not l1:
point.next=l2
else:
point.next=l1
return head.next
运行结果
时间复杂度: ,其中k是链表的数目。
- 我们可以在的时间内合并两个有序链表,其中 n是两个链表中的总节点数。
- 将所有的合并进程加起来,我们可以得到:
空间复杂度:O(1).