题目:21. 合并两个有序链表
21. 合并两个有序链表
难度简单
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
示例 2:
输入:l1 = [], l2 = []
输出:[]
示例 3:
输入:l1 = [], l2 = [0]
输出:[0]
提示:
- 两个链表的节点数目范围是
[0, 50]
-100 <= Node.val <= 100
l1
和l2
均按 非递减顺序 排列
解题思路
递归
通过返回后续链表的最小结点,当前结点去链接起来就可以了。
迭代
通过一个临时结点tmp指向合并了的链表的尾结点,然后将两个链表中的最小结点链接到tmp的后面,tmp重新指向尾结点。
代码
ListNode* initList(int start, int num, int gap)
{
srand(time(NULL));
ListNode* head0 = new ListNode(start);
ListNode* head = head0;
for (int i = 1; i < num; i++)
{
ListNode* mNode = new ListNode(start + i * gap);
head0->next = mNode;
head0 = head0->next;
}
return head;
}
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
void printList(ListNode* head) {
while (head) {
cout << head->val << " ";
head = head->next;
}
cout << endl;
}
class Solution {
public:
ListNode* mergeTwoLists1(ListNode* l1, ListNode* l2) {
// 如果都为空,返回另一个指针与NULL都一样
// 如果有一个为空,另一个也没有递归的必要了,没啥可排序的
if (!l1) return l2;
if (!l2) return l1;
// 如果是l2比较小, 将小的节点返回出去
if (l1->val > l2->val) {
// 链接后面链表给的最小的节点
l2->next = mergeTwoLists(l1, l2->next);
return l2;
}
// 链接后面链表给的最小的节点
l1->next = mergeTwoLists(l1->next, l2);
return l1;
}
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
// 如果都为空,返回另一个指针与NULL都一样
// 如果有一个为空,另一个也没有递归的必要了,没啥可排序的
if (!l1) return l2;
if (!l2) return l1;
ListNode head(0);
ListNode *tmp = &head; // tmp为合并好的链表的尾结点
while (l1 && l2) {
if (l1->val < l2->val) {
tmp->next = l1;
l1 = l1->next;
}
else {
tmp->next = l2;
l2 = l2->next;
}
tmp = tmp->next;
}
if (l1)
tmp->next = l1;
else
tmp->next = l2;
return head.next;
}
};
int main()
{
ListNode * list1 = initList(1, 5, 3);
ListNode * list2 = initList(2, 5, 2);
Solution sln;
printList(list1);
printList(list2);
ListNode * ret = sln.mergeTwoLists(list1, list2);
printList(ret);
return 0;
}