【LeetCode_21】合并两个有序链表
刷爆LeetCode系列
- LeetCode第21题:
- github地址
- 前言
- 题目描述
- 题目与思路分析
- 代码实现
- 算法代码优化
LeetCode第21题:
github地址
有梦想的电信狗
前言
- 本文用
C++
解答LeetCode
第21
题
题目描述
题目链接:https://leetcode-cn.com/problems/merge-two-sorted-lists/description/
题目与思路分析
目标分析:
- 将两个升序链表合并为一个升序链表
- 返回新链表的头指针
- 新链表中的结点由已有两链表中的节点组成
- 提高要求:时间复杂度为
O(n)
,空间复杂度为O(1)
思路:创建一个新的空链表newHead
,同时逐个遍历两个链表的结点,将val较小的节点尾插到新链表中
操作:
-
注意对空链表的处理,两个链表可能都为空,也可能任意一个为空
-
遍历:循环继续的条件为
curNode1 && curNode2
,只要有一个链表结束,结束即可,将未遍历完的链表直接整体尾插到新链表中curNode1
和curNode2
:分别用于遍历链表一和链表二tailNode
:尾结点,方便尾插时找尾
-
curNode->val <= curNode2->val
时,说明:curNode1
需要被尾插到新链表- 第一次尾插时(
if(newHead == nullptr
)需要特殊处理:tailNode = newHead = curNode;
curNode = curNode->next;
- 其余结点的尾插,常规化处理:
tailNode->next = curNode1;
tailNode = tailNode->next;
- 插入完后:
curNode = curNode->next;
- 第一次尾插时(
-
curNode->val > curNode2->val
时和上面是一样的逻辑 -
循环结束后,检查哪个链表未遍历完全,直接整体尾插到新链表中
-
// 循环结束后,可能链表还有剩余元素if(curNode1)tailNode->next = curNode1;if(curNode2)tailNode->next = curNode2;
-
-
最终返回
return newHead;
代码实现
class Solution {
public:ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {// 空链表判断if(list1 == nullptr && list2 == nullptr)return nullptr;if(list1 == nullptr || list2 == nullptr){if(list1)return list1;if(list2)return list2;}// 以下 两个链表都不为空ListNode* curNode1 = list1;ListNode* curNode2 = list2;ListNode* newHead = nullptr, *tailNode = nullptr;while(curNode1 && curNode2){// 更小的元素尾插到新结点if(curNode1->val <= curNode2->val){// 第一个节点直接尾插if(newHead == nullptr){newHead = tailNode = curNode1;}// 其他节点直接 尾插else{tailNode->next = curNode1;tailNode = tailNode->next;}curNode1 = curNode1->next;}else{// 第一个节点直接尾插if(newHead == nullptr){newHead = curNode2;tailNode = curNode2;}// 其他节点直接 尾插else{tailNode->next = curNode2;tailNode = tailNode->next;}curNode2 = curNode2->next;}}// 循环结束后,可能链表还有剩余元素if(curNode1)tailNode->next = curNode1;if(curNode2)tailNode->next = curNode2;return newHead;}
};
算法代码优化
- 优化了空链表返回的逻辑
- 其中一个链表为空,就返回另一个链表
class Solution {
public:ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {if(list1 == nullptr)return list2;if(list2 == nullptr)return list1;// 以下 两个链表都不为空ListNode* curNode1 = list1;ListNode* curNode2 = list2;ListNode* newHead = nullptr, *tailNode = nullptr;while(curNode1 && curNode2){// 更小的元素尾插到新结点if(curNode1->val <= curNode2->val){// 第一个节点直接尾插if(newHead == nullptr){newHead = tailNode = curNode1;}// 其他节点直接 尾插else{tailNode->next = curNode1;tailNode = tailNode->next;}curNode1 = curNode1->next;}else{// 第一个节点直接尾插if(newHead == nullptr){newHead = curNode2;tailNode = curNode2;}// 其他节点直接 尾插else{tailNode->next = curNode2;tailNode = tailNode->next;}curNode2 = curNode2->next;}}// 循环结束后,可能链表还有剩余元素if(curNode1)tailNode->next = curNode1;if(curNode2)tailNode->next = curNode2;return newHead;}
};
以上就是本文的所有内容了,如果觉得文章对你有帮助,欢迎 点赞⭐收藏 支持!如有疑问或建议,请在评论区留言交流,我们一起进步
分享到此结束啦
一键三连,好运连连!
你的每一次互动,都是对作者最大的鼓励!
征程尚未结束,让我们在广阔的世界里继续前行!
🚀