输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则
方法一:递归版本
代码
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
if(!pHead1){
return pHead2;//如果其中一个为空,则返回另一个,两个都为空直接返回nullptr
}
if(!pHead2){
return pHead1;
}
if(pHead1->val<=pHead2->val){//每次取最小的作为选择节点插入merge
pHead1->next=Merge(pHead1->next,pHead2);
return pHead1;
}else{
pHead2->next=Merge(pHead1, pHead2->next);
return pHead2;
}
}
};
时间复杂度:O(m+n)
空间复杂度:O(m+n),每一次递归,递归栈都会保存一个变量,最差情况会保存(m+n)个变量
方法二:使用迭代,比递归更省空间
初始化:定义cur指向新链表的头结点
思路:
1.如果l1指向的结点值小于等于l2指向的结点值,则将l1指向的结点值链接到cur的next指针,然后l1指向下一个结点值
2.否则,让l2指向下一个结点值
3.循环步骤1,2,直到l1或者l2为nullptr
4.将l1或者l2剩下的部分链接到cur的后面
技巧
一般创建单链表,都会设一个虚拟头结点,也叫哨兵,因为这样每一个结点都有一个前驱结点。
注意:一定要对空链表处理,不处理可能导致空指针异常
代码
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
if(!pHead1){
return pHead2;//如果其中一个为空,则返回另一个,两个都为空直接返回nullptr
}
if(!pHead2){
return pHead1;
}
ListNode *vHead=new ListNode(-1);//虚拟头结点,类似与哨兵,记录头节点位置
ListNode *cur=vHead;//初始化和vHead一样,在迭代的过程改变
while(pHead1&&pHead2){
//当两个链表的长度都满足条件
if(pHead1->val<=pHead2->val){
cur->next=pHead1;
pHead1=pHead1->next;
}else{
cur->next=pHead2;
pHead2=pHead2->next;
}
cur=cur->next;//注意:每判断完一个结点cur指针要后移
}
cur->next=pHead1?pHead1:pHead2;//将两个链表中剩下的那个链接到cur->next
return vHead->next;//返回虚拟头结点的下一个
}
};
时间复杂度:O(m+n),m,n分别为两个单链表的长度
空间复杂度:O(1)