文章目录
- 问题描述
- 示例1
- 示例2
- 示例3
- 提示
- 思路分析
- 代码分析
- 完整代码
- 额外讲解
- 完结
问题描述
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
示例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
思路分析
-
首先,定义一个辅助方法
mergeTwoLists
,用于将两个有序链表合并成一个有序链表。 -
接着,定义一个辅助方法
mergeKListsHelper
,该方法接收一个链表数组lists
、起始索引start
和结束索引end
,返回合并后的链表。 -
在
mergeKListsHelper
方法中,首先判断起始索引start
是否大于结束索引end
,如果是,则直接返回None
。 -
然后,判断起始索引
start
是否等于结束索引end
,如果是,则说明只有一个链表需要合并,直接返回该链表即可。 -
如果起始索引
start
小于结束索引end
,则计算中间索引mid
,将链表数组拆分成两个部分。 -
调用递归方法
mergeKListsHelper
,分别传入起始索引start
和中间索引mid
,得到合并后的左半部分链表。 -
同样地,调用递归方法
mergeKListsHelper
,分别传入中间索引mid+1
和结束索引end
,得到合并后的右半部分链表。 -
最后,调用辅助方法
mergeTwoLists
,将左半部分链表和右半部分链表合并成一个有序链表,并返回合并后的结果。 -
最后,在主方法
mergeKLists
中,判断链表数组lists
是否为空,如果为空,则直接返回None
。 -
否则,调用辅助方法
mergeKListsHelper
,传入链表数组lists
、起始索引0 和结束索引len(lists)-1
,得到最终合并后的链表。
代码分析
第1块:
class Solution(object):
def mergeKLists(self, lists):
"""
:type lists: List[ListNode]
:rtype: ListNode
"""
定义了一个名为 Solution
的类,该类包含一个方法 mergeKLists
,接收一个参数 lists
,并且没有指定返回类型。
第2块:
if not lists:
return None
判断链表数组 lists
是否为空,如果为空,则直接返回 None
。
第3块:
n = len(lists)
获取链表数组 lists
的长度,并将其赋值给变量 n
。
第4块:
while n > 1:
k = (n + 1) // 2
for i in range(n // 2):
lists[i] = self.mergeTwoLists(lists[i], lists[i+k])
n = k
使用循环进行链表的合并操作。首先判断 n
是否大于1,即还有多个链表需要合并。然后计算中间位置的索引并赋值给变量 k
。接着使用循环遍历链表数组的前一半元素的索引,调用辅助方法 mergeTwoLists
对当前元素和对应的后半部分元素进行合并,并将结果赋值给当前元素。最后将数组长度更新为中间位置,并继续下一轮循环。
第5块:
return lists[0]
返回合并后的链表数组的第一个元素,即最终合并后的链表。
第6块:
def mergeTwoLists(self, 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
定义了一个辅助函数 mergeTwoLists
,接收两个参数 l1
和 l2
。该函数用于合并两个有序链表。首先判断链表 l1
是否为空,如果为空,则直接返回链表 l2
。然后判断链表 l2
是否为空,如果为空,则直接返回链表 l1
。接着判断链表 l1
的头结点的值是否小于链表 l2
的头结点的值。如果成立,将链表 l1
的下一个节点和链表 l2
传入递归调用的 mergeTwoLists
方法,并将返回的结果赋值给链表 l1
的下一个节点,并返回链表 l1
。如果不成立,则将链表 l1
和链表 l2
的下一个节点传入递归调用的 mergeTwoLists
方法,并将返回的结果赋值给链表 l2
的下一个节点,并返回链表 l2
。
完整代码
class Solution(object):
def mergeKLists(self, lists):
"""
:type lists: List[ListNode]
:rtype: ListNode
"""
if not lists: # 如果链表列表为空
return None # 返回 None
n = len(lists) # 获取链表列表的长度,并赋值给变量 n
while n > 1: # 当链表列表的长度大于 1 时,进行循环操作
k = (n + 1) // 2 # 计算中间位置 k
for i in range(n // 2): # 对于每个索引 i,进行以下操作
lists[i] = self.mergeTwoLists(lists[i], lists[i+k]) # 将 lists[i] 和 lists[i+k] 进行合并,并赋值给 lists[i]
n = k # 将 n 更新为 k,继续下一轮循环
return lists[0] # 返回合并后的链表列表的第一个元素,即最终合并后的链表
def mergeTwoLists(self, l1, l2):
if not l1: # 如果 l1 为空
return l2 # 直接返回 l2
if not l2: # 如果 l2 为空
return l1 # 直接返回 l1
if l1.val < l2.val: # 如果 l1 的头结点的值小于 l2 的头结点的值
l1.next = self.mergeTwoLists(l1.next, l2) # 将 l1 的下一个节点与递归调用的 self.mergeTwoLists(l1.next, l2) 结果进行合并,并赋值给 l1.next
return l1 # 返回 l1
else: # 否则
l2.next = self.mergeTwoLists(l1, l2.next) # 将 l1 和 l2 的下一个节点与递归调用的 self.mergeTwoLists(l1, l2.next) 结果进行合并,并赋值给 l2.next
return l2 # 返回 l2
额外讲解
-
class Solution(object):
:定义了一个名为Solution
的类。 -
def mergeKLists(self, lists):
:定义了一个方法mergeKLists
,接收一个参数lists
。 -
if not lists:
:判断链表数组lists
是否为空。如果为空,则直接返回None
。 -
n = len(lists)
:获取链表数组的长度。 -
while n > 1:
:进入循环,条件是链表数组的长度大于1,即还有多个链表需要合并。 -
k = (n + 1) // 2
:计算中间位置的索引。 -
for i in range(n // 2):
:遍历链表数组的前一半元素的索引。 -
lists[i] = self.mergeTwoLists(lists[i], lists[i+k])
:调用辅助方法mergeTwoLists
,将当前元素和对应的后半部分元素进行合并,并将结果赋值给当前元素。 -
n = k
:更新链表数组的长度为中间位置。 -
return lists[0]
:返回合并后的链表数组的第一个元素,也就是最终合并后的链表。 -
def mergeTwoLists(self, l1, l2):
:定义了一个辅助函数mergeTwoLists
,接收两个参数l1
和l2
。 -
if not l1:
:判断链表l1
是否为空。如果为空,则直接返回l2
。 -
if not l2:
:判断链表l2
是否为空。如果为空,则直接返回l1
。 -
if l1.val < l2.val:
:判断链表l1
的头结点的值是否小于链表l2
的头结点的值。 -
l1.next = self.mergeTwoLists(l1.next, l2)
:递归调用mergeTwoLists
方法,将l1
的下一个节点和l2
传入,并将返回的结果赋值给l1
的下一个节点。 -
return l1
:返回合并后的链表l1
。 -
else:
:如果链表l1
的头结点的值大于等于链表l2
的头结点的值。 -
l2.next = self.mergeTwoLists(l1, l2.next)
:递归调用mergeTwoLists
方法,将l1
和l2
的下一个节点传入,并将返回的结果赋值给l2
的下一个节点。 -
return l2
:返回合并后的链表l2
。