题目
输入两个递增的链表,单个链表的长度为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
输入:
{},{}
返回值:
{}
示例
输入:
{-1,2,4},{1,3,4}
返回值:
{-1,1,2,3,4,4}
思路1
将链表头小的作为主链表,将另一个链表插入其中。
解答代码1
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) : val(x), next(nullptr) {}
* };
*/
class Solution {
public:
/**
* @param pHead1 ListNode类
* @param pHead2 ListNode类
* @return ListNode类
*/
ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
// write code here
if (pHead1 == nullptr && pHead2 == nullptr) {
return nullptr;
} else if (pHead1 != nullptr && pHead2 == nullptr) {
return pHead1;
} else if (pHead1 == nullptr && pHead2 != nullptr) {
return pHead2;
}
ListNode* low = nullptr;// 头结点小的链表
ListNode* top = nullptr;// 头结点大的链表
if (pHead1->val <= pHead2->val) {
low = pHead1;
top = pHead2;
} else {
low = pHead2;
top = pHead1;
}
ListNode* ret = low;// 结果指向头结点小的链表,将头结点大的链表数据往里面插入
ListNode* tmp = nullptr;// 临时节点做缓存
while (low->next != nullptr && top != nullptr) {// 循环到某个链表为空
// 结果链表中当前值为最小值,比较low的next的值和top的当前值
// 如果大于等于,则将top的当前值插入到low当前值的后面
if (low->next->val >= top->val) {
tmp = low->next;// 讲tmp指向low的next,临时缓存low的next
low->next = top;// 将low的next指向top的当前值
top = top->next;// 让top指针后移
low->next->next =
tmp;// 新插入top(新的low的next)的next指向tmp,也就是缓冲的之前的low的next
}
low = low->next; // 让low指针后移
}
// 如果头结点小的链表先循环完,则将top剩余的插入到结果后面
if (low->next == nullptr) {
low->next = top;
}
return ret;
}
};
思路2
创建一个新链表,将两个旧链表按顺序合入,至一个链表为空,将另一个链表接在后面。
解答代码2
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) : val(x), next(nullptr) {}
* };
*/
class Solution {
public:
/**
* @param pHead1 ListNode类
* @param pHead2 ListNode类
* @return ListNode类
*/
ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
// write code here
if (pHead1 == nullptr && pHead2 == nullptr) {
return nullptr;
} else if (pHead1 != nullptr && pHead2 == nullptr) {
return pHead1;
} else if (pHead1 == nullptr && pHead2 != nullptr) {
return pHead2;
}
auto new_head = new ListNode(0);// 定义一个头结点
auto cur = new_head;// 让当前节点指向头结点
while (pHead1 != nullptr && pHead2 != nullptr) {
// 取较小的节点加入新表
if (pHead1->val <= pHead2->val) {
cur->next = pHead1;
pHead1 = pHead1->next;
} else {
cur->next = pHead2;
pHead2 = pHead2->next;
}
cur = cur->next;
}
// 将没有空的链表加到新表后
if (pHead1 != nullptr) {
cur->next = pHead1;
}
if (pHead2 != nullptr) {
cur->next = pHead2;
}
return new_head->next;// 返回结果不要最开始的头结点
}
};
ps:一般创建单链表,都会设一个虚拟头结点,也叫哨兵,因为这样每一个结点都有一个前驱结点。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。