合并两个有序链表
问题描述
输入两个单调递增的链表,输出两个链表合成后的链表,我们需要合成后的链表满足单调不减规则。
示例:
输入: {1,3,5},{2,4,6}
返回值: {1,2,3,4,5,6}
分析问题
既然给定的两个链表都是有序的,那么我们可以判断两个链表的头结点的值的大小,将较小值的结点添加到结果中,然后将对应链表的结点指针后移一位,循环往复,直到有一个链表为空为止。
由于链表是有序的,所以循环终止时,那个非空的链表中的元素都比前面已经合并的链表中的元素大,所以,我们只需要简单地将非空链表接在合并链表的后面,并返回合并链表即可。
首先我们需要先创建一个哨兵节点,然后将prehead指向链表l1和l2中比较小的一个。如果相等的话,指向任意一个即可。然后将较小值对应的链表的指针后移一位。
更多题解,关注公众号《程序员学长》,让你进大厂不走弯路
我们下面来看一下代码实现。
def mergeTwoLists(self, l1, l2):
#合并后链表的哨兵结点
head=ListNode(-1,None)
pre=head
#循环遍历,将两个链表中的较小值插入到合并后的链表中
while l1 and l2:
if l1.val <= l2.val:
pre.next=l1
l1=l1.next
else:
pre.next=l2
l2=l2.next
pre=pre.next
#将剩余的非空链表插入到合并链表的后面
if l1:
pre.next=l1
else:
pre.next=l2
return head.next
其实,我们这里也可以使用递归的方式来实现。
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def mergeTwoLists(self, l1, l2):
#链表l1为空,不需要合并,直接返回l2
if(l1==None):
return l2
#同理,l2为空,直接返回l1即可
if(l2==None):
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
问题升级
下面,我们来把问题升级一下,将两个有序链表合并改成多个有序链表合并,我们来看一下题目。
给定一个有序链表, 其中每个节点也表示有一个有序链表。结点包含两个类型的指针:
- 指向主链表中下一个结点的指针。
- 指向以此结点为头的链表。
示例如下所示:
4 -> 9 -> 15 -> 19
| | | |
7 13 18 28
| | |
8 21 37
|
20
实现函数flatten(),该函数用来将链表扁平化成单个链表。例如上面的链表,输出链表为
4 -> 7 -> 8 -> 9 -> 13 -> 15 -> 18 ->19 -> 20 -> 21 -> 28 -> 37
题目要求我们把二维有序链表合并成一个单链表,我们来把问题简化一下,假设主链表只有两个节点,即这个二维链表变成如下所示。
4 -> 9
| |
7 13 旋转一下 4 -> 7 -> 8 -> 20
| ----------> |
8 9 -> 13
|
20
这不就是我们上面讲的两个有序链表合并吗?那如果主链表有多个节点呢?我们可以使用归并的思想,逐个去合并就好了,如下图所示。
下面我们来看一下代码如何实现。
class ListNode:
def __init__(self, val=0, right=None, down=None):
self.val = val
self.right = right
self.down = down
class Solution:
def mergeTwoLists(self, l1, l2):
#如果有一个链表为空,则合并后的链表就是另外一个
if(l1==None):
return l2
if(l2==None):
return l1
if(l1.val<=l2.val):
l1.down=self.mergeTwoLists(l1.down,l2)
return l1
else:
l2.down=self.mergeTwoLists(l1,l2.down)
return l2
def flatten(self,root):
if root== None or root.right == None:
return root
#把root->right 看作是已经有序的单链表,
#然后通过递归来进行归并
return self.mergeTwoLists(root, self.flatten(root.right))