文章目录
一、题目描述
给定两个 升序排列的单链表 list1 和 list2,请将它们 合并成一个新的升序链表,并返回合并后的链表。
示例输入:
list1 = [1,2,4]
list2 = [1,3,4]
输出:
[1,1,2,3,4,4]
二、题目理解与分析
两条有序链表,核心操作是逐节点比较两条链表的当前节点值,挑出更小的放入新链表中。
📌 可类比归并排序中的合并过程。
三、思维导图(mermaid)
合并两个有序链表
原始输入
list1: 1->2->4
list2: 1->3->4
解法思路
迭代法
使用虚拟头结点
递归法
按较小值递归连接
关键操作
比较当前节点值
移动指针
输出结果
新链表:1->1->2->3->4->4
四、解决方案一:迭代法
原理讲解
- 建立一个 虚拟头节点(dummy),方便操作,不需要额外处理链表头。
- 使用指针
cur指向当前操作位置。 - 当两条链表都未结束时:
- 比较
list1.val与list2.val - 连接较小的节点到
cur.next - 将相应链表指针后移
- 比较
- 合并完成后,如果其中一条链表尚未结束,直接将其接在结果链表尾部。
流程图(mermaid)
是
是
否
否
开始
list1 和 list2 均非空?
list1.val < list2.val?
连接 list1 节点到结果链表
移动 list1 指针
连接 list2 节点到结果链表
移动 list2 指针
将剩余链表连接到结果链表尾部
返回结果链表头(dummy.next)
结束
Java代码实现
java
class ListNode {
int val;
ListNode next;
ListNode(int val) { this.val = val; }
}
public class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
// 创建虚拟头结点,方便操作
ListNode dummy = new ListNode(-1);
ListNode cur = dummy;
while (list1 != null && list2 != null) {
if (list1.val <= list2.val) {
cur.next = list1;
list1 = list1.next;
} else {
cur.next = list2;
list2 = list2.next;
}
cur = cur.next;
}
// 剩余链表直接连接
cur.next = (list1 != null) ? list1 : list2;
return dummy.next;
}
}
时间复杂度与空间复杂度分析
| 项目 | 分析 |
|---|---|
| 时间复杂度 | O(m + n),m、n 分别为两个链表长度,每个节点仅访问一次。 |
| 空间复杂度 | O(1),只使用常数级额外空间(除了输入链表的节点外)。 |
五、解决方案二:递归法
原理讲解
递归思想非常优美:
- 若
list1或list2为null,返回另一条。 - 比较两链表头节点:
- 若
list1.val < list2.val:
list1.next = mergeTwoLists(list1.next, list2)
返回list1 - 否则:
list2.next = mergeTwoLists(list1, list2.next)
返回list2
- 若
时序图(mermaid)
mergeTwoLists() List2 List1 mergeTwoLists() List2 List1 调用 mergeTwoLists(list1, list2) 比较 list1.val 与 list2.val 若 list1.val < list2.val,则递归 list1.next 与 list2 否则递归 list1 与 list2.next 每次返回较小节点作为当前结果 最终返回合并后的头节点
Java代码实现
java
public class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
if (list1 == null) return list2;
if (list2 == null) return list1;
if (list1.val <= list2.val) {
list1.next = mergeTwoLists(list1.next, list2);
return list1;
} else {
list2.next = mergeTwoLists(list1, list2.next);
return list2;
}
}
}
时间复杂度与空间复杂度分析
| 项目 | 分析 |
|---|---|
| 时间复杂度 | O(m + n),仍然是遍历所有节点一次。 |
| 空间复杂度 | O(m + n),递归调用栈深度最多等于节点总数。 |
六、总结
| 解法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 迭代法 | 时间效率高;不占用额外栈空间 | 代码略冗长 | 大多数实际业务逻辑中推荐使用 |
| 递归法 | 代码简洁美观;逻辑清晰 | 可能导致栈溢出 | 递归深度较小的场景,或用于教学演示 |