前言
链表是数据结构中最为基础和重要的一部分,围绕链表的算法题层出不穷,“合并K个(≥2个)有序的链表”类似问题就是其中一类,有一定的参考价值。
目录
合并2个有序链表
要求:将两个已经排序的链表合并成一个更大的链表并返回。
分析:
本题的解题思路有两个重要因素:一个是构造指针进行遍历和判断;另一个是对于特殊情况(如链表均为空)的处理。
下面我们分别来看。
构造指针进行遍历和判断
因为存在两个链表,而为了得到所有数字,这两个链表显然我们都是要进行遍历的。
因此,对每个链表设一个指针进行这件事:
while list1 and list2:
if list1.val <= list2.val:
p.next = list1
list1 = list1.next
else:
p.next = list2
list2 = list2.next
p = p.next
可以注意到的是,我直接用了list1和list2进行这项遍历任务。
除了l1和l2,还有一个p是什么呢?
我们知道,遍历的结果需要储存,而p就是我们构造出来的、用来存放大链表的这个新链表。
此外,还有一点需要注意:
我们在如此操作之后,l1或l2的其中一个会剩下没有处理完的节点(显然这些节点的值是足够大的,比另一个链表最后一个还大),那么我们可以直接把这些节点跟在p的后面。
if list1:
p.next = list1
else:
p.next = list2
对于特殊情况(链表为空)的处理
虽然很简单,但是也需要处理特殊情况:如果l1或者l1和l2都是空的链表,我们该怎么处理呢?
根据上述的代码,显然并不满足“while list1 and list2”,因此我们需要额外在开头进行判断。
当然,我们也可以用虚拟头节点来规避这件事:
dummy = ListNode(-1)
p = dummy
我们设一个虚拟的节点dummy,使得它的next是原本的head即可。
完整代码:
class Solution:
def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
dummy = ListNode(-1)
p = dummy
while list1 and list2:
if list1.val <= list2.val:
p.next = list1
list1 = list1.next
else:
p.next = list2
list2 = list2.next
p = p.next
if list1:
p.next = list1
else:
p.next = list2
return dummy.next
合并K个有序链表(K>2)
直接上图: