持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第17天,点击查看活动详情
题目
描述
输入两个递增的链表,单个链表的长度为n,合并这两个链表并使新链表中的节点仍然是递增排序的。
数据范围: 0≤n≤1000,−1000≤节点值≤1000 要求:空间复杂度 O(1),时间复杂度 O(n)
如输入{1,3,5},{2,4,6}时,合并后的链表为{1,2,3,4,5,6},所以对应的输出为{1,2,3,4,5,6},转换过程如下图所示:
或输入{-1,2,4},{1,3,4}时,合并后的链表为{-1,1,2,3,4,4},所以对应的输出为{-1,1,2,3,4,4},转换过程如下图所示:
示例1
输入:
{1,3,5},{2,4,6}
返回值:
{1,2,3,4,5,6}
示例2
输入:
{},{}
返回值:
{}
示例3
输入:
{-1,2,4},{1,3,4}
返回值:
{-1,1,2,3,4,4}
分析
考虑特殊情况
在进行问题分析过程前,我们先考虑一下特殊情况,那么在这道问题中,有哪些情况是特殊的呢?
不难发现,如下情况:
- pHead1是空链表或者pHead2是空链表,那么我们只需要返回对方即可
当然两者都是空链表的情况返回对方也是可以的
考虑一般情况
由于需要按顺序排列,这里我们最先想到的就是使用两个指针分别遍历两个链表,直到两个指针中出现空指针的情况,在遍历过程中,做如下判断:
- 如果链表1的元素小于链表2的元素,那么先链接1的元素,链表1的指针后移;
- 否则,先链接2的元素,链表2的指针后移。
出现一个链表指针为空的情况,说明另一个链表的元素都比之前的元素大,这时只需要将剩余的元素链接到末尾即可。
代码示例
注意,这里还做了一些额外的处理:
- pReturn:记录返回的头结点,指向较小的头结点;
- pCur0:记录merge链表的当前位置;
- pCur1:记录链表1的当前位置;
- pCur2:记录链表2的当前位置。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
// special condition
if (nullptr == pHead1) {
return pHead2;
}
if (nullptr == pHead2) {
return pHead1;
}
ListNode* pReturn = nullptr;
ListNode* pCur0 = nullptr;
ListNode* pCur1 = pHead1;
ListNode* pCur2 = pHead2;
// assign the pReturn
if (pHead1->val <= pHead2->val) {
pReturn = pHead1;
pCur1 = pCur1->next;
} else {
pReturn = pHead2;
pCur2 = pCur2->next;
}
pCur0 = pReturn;
// traverse the two list and link them
while(nullptr != pCur1 && nullptr != pCur2){
if(pCur1->val <= pCur2->val){
pCur0->next = pCur1;
pCur1 = pCur1->next;
}else{
pCur0->next = pCur2;
pCur2 = pCur2->next;
}
pCur0 = pCur0->next;
}
if(nullptr == pCur1){
pCur0->next = pCur2;
}else if(nullptr == pCur2){
pCur0->next = pCur1;
}
return pReturn;
}
};