概述
LeetCode题目(Python实现):合并K个排序链表
- 题目
- 想法一:分治法
- 算法实现
- 执行结果
- 复杂度分析
- 暴力法
- 算法实现
- 执行结果
- 复杂度分析
- 分治法(官方)
- 算法实现
- 执行结果
- 复杂度分析
- 小结
题目
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例 :
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
想法一:分治法
算法实现
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
n = len(lists)
if n == 0:
return None
elif n == 1:
return lists[0]
i = 1
while i < n:
j = 0
while j + i < n:
lists[j] = self.mergeTwoLists(lists[j], lists[j + i])
j += i * 2
i *= 2
return lists[0]
def mergeTwoLists(self,l1: ListNode, l2: ListNode) -> ListNode:
prehead = ListNode(-1)
prev = prehead
while l1 and l2:
if l1.val <= l2.val:
prev.next = l1
l1 = l1.next
else:
prev.next = l2
l2 = l2.next
prev = prev.next
prev.next = l1 if l1 is not None else l2
return prehead.next
执行结果
执行结果 : 通过
执行用时 : 88 ms, 在所有 Python3 提交中击败了93.60%的用户
内存消耗 : 16.5 MB, 在所有 Python3 提交中击败了44.78%的用户
复杂度分析
- 时间复杂度:完蛋,自己分析不出来,尴尬,只能看官方了:O(kN) ,其中 k 是链表的数目。
- 我们可以在 O(n) 的时间内合并两个有序链表,其中 n 是两个链表的总长度。
- 把所有合并过程所需的时间加起来,我们可以得到:
- 空间复杂度:O(1),
我们可以在 O(1) 空间内合并两个有序链表。
暴力法
算法实现
def mergeKLists(self, lists):
"""
:type lists: List[ListNode]
:rtype: ListNode
"""
self.nodes = []
head = point = ListNode(0)
for l in lists:
while l:
self.nodes.append(l.val)
l = l.next
for x in sorted(self.nodes):
point.next = ListNode(x)
point = point.next
return head.next
执行结果
复杂度分析
- 时间复杂度:O(N log N) ,其中 N 是链表的数目。
- 遍历所有的值需花费 O(N)O(N) 的时间。
- 一个稳定的排序算法花费 O(Nlog N)O(NlogN) 的时间。
- 遍历同时创建新的有序链表花费 O(N)O(N) 的时间。
- 空间复杂度:O(N)
- 排序花费 O(N)O(N) 空间(这取决于你选择的算法)。
- 创建一个新的链表花费 O(N)O(N) 的空间。
分治法(官方)
算法实现
def mergeKLists(self, lists):
"""
:type lists: List[ListNode]
:rtype: ListNode
"""
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
执行结果
复杂度分析
同上
小结
先按照自己的想法设计,分治法每两个合并一次,第一次步长为1,第二次为2,第n次步长为2^(n-1),最后合并出结果,而合并两个有序链表之前已经写过函数,直接调用即可(调用的是迭代法)。
意外的是暴力法,没想到暴力法也有出头的一天,哈哈。
最后
以上就是阔达小馒头为你收集整理的LeetCode题目(Python实现):合并K个排序链表题目的全部内容,希望文章能够帮你解决LeetCode题目(Python实现):合并K个排序链表题目所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复