描述
这是一篇面对初级coder的题解。
知识点:链表
难度:二星
题解
题目:输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
考察链表的基础知识
方法一:采用新链表合并
思路:创建一个新链表,将两个旧链表按顺序合入,至一个链表为空,将另一个链表接在后面。
算法流程:
初始化: 伪头节点
初始化: 伪头节点
ListNode* vhead=new ListNode(-1); //一个技巧 初始化虚拟虚拟头结点,使每一个结点都有一个前驱结点便于循环
循环合并:
if(pHead1->val<=pHead2->val) //哪个链表头节点小从哪个链表拿
{
newhead->next=pHead1; //取节点
pHead1=pHead1->next;//后移对应链表
}
else//同理
{
newhead->next=pHead2;
pHead2=pHead2->next;
}
newhead=newhead->next;//将新链表后移 为空时跳出;
while(pHead1&&pHead2)//终止条件 一个链表为空
合并剩余尾部: 跳出时有两种情况,
if(pHead2==nullptr) //将剩余的链表拼在后面 newhead->next=pHead1; if(pHead1==nullptr) newhead->next=pHead2;
返回值: 合并链表在伪头节点 之后,因此返回
vhead->next即可。
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
ListNode* vhead=new ListNode(-1); //一个技巧 初始化虚拟虚拟头结点,使每一个结点都有一个前驱结点便于循环
ListNode *newhead=vhead;
while(pHead1&&pHead2)//终止条件 一个链表为空
{
if(pHead1->val<=pHead2->val) //哪个链表头节点小从哪个链表拿
{
newhead->next=pHead1; //取节点
pHead1=pHead1->next;//后移对应链表
}
else//同理
{
newhead->next=pHead2;
pHead2=pHead2->next;
}
newhead=newhead->next;//将新链表后移
}
if(pHead2==nullptr) //将剩余的链表拼在后面
newhead->next=pHead1;
if(pHead1==nullptr)
newhead->next=pHead2;
return vhead->next;
}
}; 运行时间: 5 ms 占用内存:608K
方法二:插入
将链表头小的作为主链表,将另一个链表插入其中
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
ListNode* ans;// 答案输出
ListNode *temp;//插入缓存
//防止一个链表为空 返回另一个
if(!pHead1)
return pHead2;
if(!pHead2)
return pHead1;
if(pHead1->val>pHead2->val) //哪个链表头节点小从哪个链表拿 保证是将pHead2插入pHead1
{
temp=pHead1;
pHead1=pHead2;
pHead2=temp;
}
ans=pHead1;
while(pHead1->next&&pHead2)//终止条件 一个链表为空
{
if(pHead1->next->val>pHead2->val) //
{
temp=pHead1->next;//插入
pHead1->next=pHead2;
pHead2=pHead2->next;//后移对应链表2
pHead1->next->next=temp;
}
pHead1=pHead1->next;//后移对应链表1
}
if(pHead1->next==nullptr) //将剩余的链表2拼在后面
pHead1->next=pHead2;
return ans;
}
};
两个表都遍历了一遍,时间复杂度O(m+n),同时由于没开新的空间存放表其中mn是两个链表的长度
空间复杂度O(1)
运行时间: 12 ms 占用内存:540K
总结
各位牛友在练习的时候要注意边界条件的判定
一般创建单链表,都会设一个虚拟头结点,也叫哨兵,因为这样每一个结点都有一个前驱结点。

京公网安备 11010502036488号