将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
思路1:
混插,比较list1和list2,将list1插入到list2中,或者将list2插入到list1中,这种方式比较麻烦,不推荐。
思路2:
依次比较两个链表结点,取小的那个结点尾插到新链表中。
初始条件:
要记住新链表的头结点,使用指针head来记录新链表的头结点
使用指针tail来记录新链表的尾结点
对于第一个结点的插入,要特别注意,第一个结点插入后,head的位置就固定了,不需要再改变
写法1:
struct ListNode
{
int val;
struct ListNode* next;
};
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
if (list1 == NULL)
{
return list2;
}
if (list2 == NULL)
{
return list1;
}
//初始条件
struct ListNode* head = NULL;
struct ListNode* tail = NULL;
//list1和list2只要有一个没有结点了,循环停止
while (list1 != NULL && list2 != NULL)
{
//list1小
if (list1->val <= list2->val)
{
//尾插
//插入第一个结点时,记住头结点位置
if (head == NULL)
{
head = list1;
tail = list1;
}
else
{
//插入其他结点
tail->next = list1;
tail = list1;
}
//list1继续向后走
list1 = list1->next;
}
else
{
//list2小
//尾插
//插入第一个结点时,记住头结点位置
if (head == NULL)
{
head = list2;
tail = list2;
}
else
{
//插入其他结点
tail->next = list2;
tail = list2;
}
//list2继续向后走
list2 = list2->next;
}
}
//如果list1没有结点了
if (list2 != NULL)
{
tail->next = list2;
}
//如果list2没有结点了
if (list1 != NULL)
{
tail->next = list1;
}
return head;
}
写法2:
对于新链表第一个结点的插入,可以单独拿出来做处理
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
if (list1 == NULL)
{
return list2;
}
if (list2 == NULL)
{
return list1;
}
struct ListNode* head = NULL;
struct ListNode* tail = NULL;
//先处理第一个结点
if (list1->val <= list2->val)
{
head = list1;
tail = list1;
//list1继续向后走
list1 = list1->next;
}
else
{
head = list2;
tail = list2;
//list2继续向后走
list2 = list2->next;
}
//继续处理后面的结点
while (list1 != NULL && list2 != NULL)
{
if (list1->val <= list2->val)
{
//尾插
tail->next = list1;
tail = list1;
//list1继续向后走
list1 = list1->next;
}
else
{
//尾插
tail->next = list2;
tail = list2;
//list2继续向后走
list2 = list2->next;
}
}
//如果list1没有结点了
if (list2 != NULL)
{
tail->next = list2;
}
//如果list2没有结点了
if (list1 != NULL)
{
tail->next = list1;
}
return head;
}
写法3:选择带哨兵位的链表
哨兵位结点没有有效数据
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
if (list1 == NULL)
{
return list2;
}
if (list2 == NULL)
{
return list1;
}
struct ListNode* head = NULL;
struct ListNode* tail = NULL;
//带哨兵位的头结点
head = tail = (struct ListNode*)malloc(sizeof(struct ListNode));
while (list1 != NULL && list2 != NULL)
{
if (list1->val <= list2->val)
{
//尾插
tail->next = list1;
tail = list1;
//list1继续向后走
list1 = list1->next;
}
else
{
//尾插
tail->next = list2;
tail = list2;
//list2继续向后走
list2 = list2->next;
}
}
//如果list1没有结点了
if (list2 != NULL)
{
tail->next = list2;
}
//如果list2没有结点了
if (list1 != NULL)
{
tail->next = list1;
}
struct ListNode* list = head->next;
//释放动态开辟的内存
free(head);
return list;
}