题目
将两个升序链表合并为一个新的升序链表并返回。
新链表是通过拼接给定的两个链表的所有节点组成的。
示例
输入:l1 = [1, 2, 4], l2 = [1, 3, 4]
输出:[1, 1, 2, 3, 4, 4]
输入:l1 = [ ], l2 = [ ]
输出:[ ]
输入:l1 = [ ], l2 = [0]
输出:[0]
思路
从头开始,取两个链表中较小的结点尾插到新链表中
1、定义两个指针 head 和 tail,head 是哨兵位结点,最后 return 的是 head->next
2、l1 结点值等于 l2,将 l1 结点(l2 结点亦可)链接到 tail 结点的后面,然后 l1 指针和 tail 指针往后移
3、再次比较 l1 和 l2的值,将较小结点链接到 tail 结点的后面,指针继续后移
循环上述步骤,直至某个链表遍历完成,最后将另一个链表剩余的部分链接到 tail 的后面
代码实现
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
if(list1 == NULL)
return list2;
if(list2 == NULL)
return list1;
struct ListNode* head = NULL, *tail = NULL;
//哨兵位
head = tail = (struct ListNode*)malloc(sizeof(struct ListNode));
while(list1 != NULL && list2 != NULL)
{
if(list1->val < list2->val)
{
//尾插
tail->next = list1;
list1 = list1->next;
}
else
{
tail->next = list2;
list2 = list2->next;
}
tail = tail->next;
}
if(list1)
tail->next = list1;
if(list2)
tail->next = list2;
struct ListNode* first = head->next;
free(head);
head = NULL;
return first;
}
如果不想要哨兵结点,可以将刚开始时 l1 和 l2 较小的结点当作头结点
代码如下
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2)
{
if(l1 == NULL)
return l1;
if(l2 == NULL)
return l2;
struct ListNode* head = NULL, *tail = NULL;
if(l1->val < l2->val)
{
head = tail = l1;
l1 = l1->next;
}
else
{
head = tail = l2;
l2 = l2->next;
}
while(l1 != NULL && l2 != NULL)
{
if(l1->val < l2->val)
{
//尾插
tail->next = l1;
l1 = l1->next;
}
else
{
tail->next = l2;
l2 = l2->next;
}
tail = tail->next;
}
if(l1)
tail->next = l1;
if(l2)
tail->next = l2;
return head;
}