剑指offer16_合并两个排序的链表_题解
合并两个排序的链表
题目描述
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
示例1
输入
{1,3,5},{2,4,6}
返回值
{1,2,3,4,5,6}
分析
方案一:迭代版本
引入伪头节点: 由于初始状态合并链表中无节点,因此循环第一轮时无法将节点添加到合并链表中。解决方案:初始化一个辅助节点 \(dum\) 作为合并链表的伪头节点,将各节点添加至 \(dum\) 之后。
/**
时间复杂度:O(n)
空间复杂度:O(1)
**/
class Solution {
public:
ListNode *Merge(ListNode *pHead1, ListNode *pHead2)
{
ListNode *dummyhead = new ListNode(-1); //虚拟头结点
ListNode *cur = dummyhead; //cur指向新链表的头结点
while (pHead1 && pHead2)
{
// 如果l1指向的结点值小于等于l2指向的结点值,则将l1指向的结点值链接到cur的next指针
if (pHead1->val <= pHead2->val)
{
cur->next = pHead1;
pHead1 = pHead1->next;
}
// 否则将l2指向的结点值链接到cur的next指针
else
{
cur->next = pHead2;
pHead2 = pHead2->next;
}
cur = cur->next;
}
//合并剩余尾部
cur->next = pHead1 ? pHead1 : pHead2;
return dummyhead->next;
}
};
方案二:递归版本
递归终止条件
①如果链表 \(l1\) 和 \(l2\) 均为空,返回空结点
②如果链表 \(l1\) 空 \(l2\) 不空,返回链表 \(l2\) 的头结点
③如果链表 \(l2\) 空 \(l1\) 空,返回链表 \(l1\) 的头结点
递归函数
如果 \(PHead1\) 的所指节点值小于等于 \(pHead2\) 所指的结点值,那么\(PHead1\) 后续节点和 \(pHead\) 节点继续递归
/**
时间复杂度:O(n)
空间复杂度:O(n)
**/
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
if (!pHead1 && !pHead2) return NULL;
if (!pHead1) return pHead2;
if (!pHead2) return pHead1;
//如果l1.val <= l2.val,那么头结点的值为l1.head的值,然后开始递归
if (pHead1->val <= pHead2->val) {
pHead1->next = Merge(pHead1->next, pHead2);
return pHead1;
}
//否则,头结点的值为l2.head的值,然后开始递归
else {
pHead2->next = Merge(pHead1, pHead2->next);
return pHead2;
}
}
};