python合并k个有序链表_Leetcode合并K个升序链表(Python版本),LeetCode,python

一、描述

给你一个链表数组,每个链表都已经按升序排列。请你将所有链表合并到一个升序链表中,返回合并后的链表。

示例 1:

输入:lists = [[1,4,5],[1,3,4],[2,6]]

输出:[1,1,2,3,4,4,5,6]

解释:链表数组如下:

[

1->4->5,

1->3->4,

2->6

]

将它们合并到一个有序链表中得到。

1->1->2->3->4->4->5->6

示例 2:

输入:lists = []

输出:[]

示例 3:

输入:lists = [[]]

输出:[]

提示:

k == lists.length

0 <= k <= 10^4

0 <= lists[i].length <= 500

-10^4 <= lists[i][j] <= 10^4

lists[i] 按 升序 排列

lists[i].length 的总和不超过 10^4

二、理解

首先,意识到数组中每个元素是一个链表,要注意和列表的区别;其次,每个链表都是升序的,因此两个链表合二为一可以在线性时间内完成。

思路

将前两个链表合二为一,将新链表与第三个链表合二为一,......,将新链表与第n个链表合二为一。

一些特殊情况为

空数组,直接返回,没有返回值,有返回值便通不过,不知是LeetCode的问题还是我理解的有问题;只有一个链表,直接返回链表头。

小技巧

提示中说明了链表元素的最小值是-10000,可提前生成一个值为-10001的链表头,否则你要在两个链表的首元素中选择一个作为链表头。

这也是为何第三部分代码最后一行是 return head.next 而不是 return head 的原因。

三、代码(初级版)

class ListNode(object):

def __init__(self, val=0, next=None):

self.val = val

self.next = next

class Solution(object):

def mergeKLists(self, lists):

"""

:type lists: List[ListNode]

:rtype: ListNode

"""

k = len(lists)

head = ListNode(val=-10001)

tail = head

if k == 0: return

if k == 1: return lists[0]

lp = lists[0]

rp = None

i = 1

# 将已完成合并的链表与当前链表数组中的第i个链表进行合并

while i < k:

rp = lists[i]

while lp and rp:

if lp.val <= rp.val:

tail.next = lp

tail = lp

lp = lp.next

else:

tail.next = rp

tail = rp

rp = rp.next

if rp: tail.next = rp

if lp: tail.next = lp

i += 1

# 如果数组没有遍历完,则重置头指针和尾指针

if i < k:

lp = head.next

head.next = None

tail = head

return head.next

上述代码虽然通过了测试,但下述结果并不是特别理想。

执行用时:3916 ms, 在所有 Python 提交中击败了15.47%的用户

内存消耗:19.1 MB, 在所有 Python 提交中击败了41.84%的用户

算法复杂度为

505c86cf07b0785bc27defa0bc054116.gif

,n 为所有的链表节点数。

四、优化版

在优化版本中,注意是意识到了可以效仿归并排序的做法,下面是代码。

# Definition for singly-linked list.

class ListNode(object):

def __init__(self, val=0, nxt=None):

self.val = val

self.next = nxt

class Solution(object):

def mergeKLists(self, lists):

"""

:type lists: List[ListNode]

:rtype: ListNode

"""

k = len(lists)

if k == 0: return

if k == 1: return lists[0]

mid = k / 2

lp = self.mergeKLists(lists[0:mid])

rp = self.mergeKLists(lists[mid:])

head = ListNode(val=-10001)

tail = head

while lp and rp:

if lp.val <= rp.val:

tail.next = lp

tail = lp

lp = lp.next

else:

tail.next = rp

tail = rp

rp = rp.next

if lp: tail.next = lp

if rp: tail.next = rp

return head.next

这次的执行结果

执行用时:92 ms, 在所有 Python 提交中击败了73.96% 的用户

内存消耗:18.9 MB, 在所有 Python 提交中击败了43.94% 的用户

算法复杂度为

1325606ef43d5368a057c5cb740b31f6.gif

,n 为所有的链表节点数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值