合并两个有序链表 | LeetCode 21 题解(C语言和java实现)
·
🌐 合并两个有序链表 | LeetCode 21 题解
嘿,代码魔术师们! 👩💻👨💻 今天我们要闯入链表的奇妙世界,探索如何合并两个有序的链表。这是 LeetCode 的第 21 题:挑战在于把两条有序链表中的元素合并成一个新的有序链表。当然,不让我们开挂,得用原地算法,节省空间!
文章目录
🧩 题目概述
🎯 目标
有两个升序的单链表 list1 和 list2,你需要把它们合并为一个升序链表。返回合并后的链表,链表应该是通过拼接 list1 和 list2 节点的方式而成,而不是创建新的节点。
💡 解题思路
1. 特殊情况处理
首先,考虑非常简单的情况:任意一条链表为空。那么,另一条链就是答案。无需多言,直接返回它即可。
2. 一般情况分析
如果两条链表都不为空,我们就需要将它们合并。在这个过程中,我们应该遵循以下步骤:
- 创建一个虚拟头节点
list3。这个节点帮我们轻松地返回合并后的链表。 - 使用一个指针
p,最初指向list3,用来追踪我们目前遍历/合并到哪个节点了。 - 依次比较两条链表当前节点的值,把较小的那个节点接到合并链表的最后。
- 当到达一条链表的末尾时,直接将另一条链表的剩余部分接到合并链的尾端。
⚙️ 操作步骤
用 C 和 Java 分别实现
C 语言版
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
// 先考虑特殊情况:有空链
if (!list1 || !list2) {
return (list1 == NULL) ? list2 : list1;
}
struct ListNode list3; // 虚拟头节点
struct ListNode *p = &list3; // 指针p用于更新list3的节点
while (list1 && list2) {
if (list1->val <= list2->val) {
p->next = list1;
list1 = list1->next;
} else {
p->next = list2;
list2 = list2->next;
}
p = p->next;
}
p->next = (list1 == NULL) ? list2 : list1;
return list3.next; // 返回头节点的下一个节点
}
Java 版
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
// 考虑特殊情况
if(list1 == null || list2 == null){
return (list1 == null) ? list2 : list1;
}
ListNode list3 = new ListNode(); // 虚拟头节点
ListNode p = list3; // p 指向 list3
while(list1 != null && list2 != null) {
if(list1.val <= list2.val){
p.next = list1;
list1 = list1.next;
} else {
p.next = list2;
list2 = list2.next;
}
p = p.next;
}
p.next = (list1 == null) ? list2 : list1;
return list3.next;
}
}
🕰️ 复杂度分析
- 时间复杂度:O(n),n 是两链表中所有节点的个数。每个节点最多被遍历一次。
- 空间复杂度:O(1),使用的空间仅仅是几个指针,实际数据操作是在原链表上完成的。
🔗 拓展阅读
对于希望深入理解链表及其操作的朋友,我强烈推荐你们探索以下内容:
🤔 实践建议
在编码时,要养成边写边测试的好习惯。尤其是处理链表的时候,检查每一个边缘条件,比如空链表和单节点链表。
🎉 互动环节
- 你在用这段代码时有遇到什么问题吗?
- 有没有比这更简洁的解决方案?欢迎在评论区分享你的见解或对代码的改进! 🌈
感谢阅读! 希望这篇文章能为你扫清代码迷雾,为你打开新世界的大门!
更多推荐


所有评论(0)