题目描述
将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
解题思路
- 首先两个链表是有序的,我们要合并成一个新的链表,就找到两个链表中表头值较小的节点作为新链表的头节点,之后每次通过操作获取
l1指向的节点
和l2指向的节点
中值较小的节点 - 为了实现这种操作,我们可以使用
递归
和迭代
两个方法
递归
- 利用递归函数的返回值,通过比较将两个链表中较小的节点作为返回值返回到上一级
- 上一级函数则直接将得到的返回值,连接到当前节点的
next
即可
函数功能
- 编写一个可以返回
l1指向的结点
和l2指向的结点
中值较小的结点,这样合并的链表才是有序的链表 - 从下级函数获得返回值连接到当前结点尾部
函数结束条件
- 当
l1为空
直接将l2剩余节点连接到尾部,当l2为空
直接将l1剩余节点连接到尾部
Cpp实现
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if (l1 == NULL) {
return l2;
}
else if (l2 == NULL) {
return l1;
}
else if (l1->val <= l2->val) {
l1->next = mergeTwoLists(l1->next, l2);
return l1;
}
else{
l2->next = mergeTwoLists(l1, l2->next);
return l2;
}
}
};
Java实现
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) return l2;
else if (l2 == null) return l1;
else if (l1.val < l2.val) {
l1.next = mergeTwoLists(l1.next, l2);
return l1;
}
else {
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}
}
Python实现
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
if not l1:
return l2
elif not l2:
return l1
elif l1.val <= l2.val:
l1.next = self.mergeTwoLists(l1.next,l2)
return l1
else:
l2.next = self.mergeTwoLists(l2.next,l1)
return l2
- 时间复杂度:O(n+m)
迭代法
- 定义一个新链表中的头节点
- 若
l1的头节点值<l2的头结点的值
,就将l1连接到头结点的next
位置 - 否则的话就将l2连接到节点的
next
位置 - 进行循环就将两个链表合并成了一个有序链表
- 最后,再将l1或l2中剩下的节点,连接到后面,这样就把两个有序链表合并成了一个有序链表
Cpp实现
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode* head = new ListNode(1);
ListNode* res = head;
while(l1 != NULL && l2 != NULL){
if(l1 -> val < l2 -> val){
head->next = l1;
l1 = l1->next;
}
else{
head->next = l2;
l2 = l2->next;
}
head = head->next;
}
head->next = l1 == NULL ? l2 : l1;
return res->next;
}
};
Java实现
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode prehead = new ListNode(-1);
ListNode mask = prehead;
while(l1 != null && l2 != null){
if(l1.val <= l2.val){
mask.next = l1;
l1 = l1.next;
}
else{
mask.next = l2;
l2 = l2.next;
}
mask = mask.next;
}
mask.next = l1 == null ? l2 : l1;
return prehead.next;
}
}
Python实现
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
res = p = ListNode(1)
while l1 or l2:
if not l1:
p.next = l2
l2 = l2.next
elif not l2:
p.next = l1
l1 = l1.next
elif l1.val <= l2.val:
p.next = l1
l1 = l1.next
else:
p.next = l2
l2 = l2.next
p = p.next
return res.next
- 时间复杂度:O(m+n)
总结
- 迭代法的实质也为递归,不过只是建立了一个新的链表来保存每次比较的结果
- 注意在迭代法过程中要设置两个指针,一个用来返回比较结果,一个用来移动并记录位置变化