一、题目描述
输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
限制:
0 <= 链表长度 <= 1000
二、思路分析
注:思路分析中的一些内容和图片参考自力扣各位前辈的题解,感谢他们的无私奉献
思路
根据题目描述, 链表 l 1 l1 l1 和 l 2 l2 l2 是递增的,因此我们可以创建一个新的节点
dum
,然后使用双指针 l 1 l1 l1 和 l 2 l2 l2 遍历两链表,根据l1->value
和l2->valuel
的大小关系确定节点添加顺序,两节点指针交替前进,直至遍历完毕。
算法流程:
①初始化: 定义头节点dum
,定义一个节点cur
指向dum,用于执行后序的插入节点操作
②开始循环:当 l 1 l1 l1 和 l 2 l2 l2 都不为空时执行循环
若l1->val<l2->val
,将 l 1 l1 l1 插入到 cur 节点后面。然后, l 1 l1 l1 和 cur 往后移动一位
若l1->val≥l2->val
,将 l 2 l2 l2 插入到 cur 节点后面。然后, l 2 l2 l2 和 cur 往后移动一位
③合并剩余尾部: 跳出循环时有两种情况,即 l 1 l1 l1 为空或 l 2 l2 l2 为空。将不为空的节点添加到cur后面
④返回值:合并链表在伪头节点 dum 之后,因此返回dum.next
即可
案例分析:
复杂度分析:
时间复杂度: O ( M + N ) \rm{O(M+N)} O(M+N):M
和N
分别为链表 l 1 l1 l1 和 l 2 l2 l2 的长度,合并操作需遍历两个链表
空间复杂度: O ( 1 ) \rm{O(1)} O(1):节点dum
和cur
使用常数大小的额外空间
三、整体代码
整体代码如下
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
struct ListNode* res = (struct ListNode*)malloc(sizeof(struct ListNode));
res->next = NULL;
struct ListNode* tmp = res;
while(l1!=NULL && l2!=NULL){
if(l1->val < l2->val){
tmp->next = l1;
l1 = l1->next;
tmp = tmp->next;
}
else {
tmp->next = l2;
l2 = l2->next;
tmp = tmp->next;
}
}
if(l1!=NULL){
tmp->next = l1;
}
else{
tmp->next = l2;
}
return res->next;
}
运行,测试通过