LeetCode Hot100(24/100)——21. 合并两个有序链表

文章目录

一、题目描述

给定两个 升序排列的单链表 list1list2,请将它们 合并成一个新的升序链表,并返回合并后的链表。

示例输入:

复制代码
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


四、解决方案一:迭代法

原理讲解

  1. 建立一个 虚拟头节点(dummy),方便操作,不需要额外处理链表头。
  2. 使用指针 cur 指向当前操作位置。
  3. 当两条链表都未结束时:
    • 比较 list1.vallist2.val
    • 连接较小的节点到 cur.next
    • 将相应链表指针后移
  4. 合并完成后,如果其中一条链表尚未结束,直接将其接在结果链表尾部。

流程图(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),只使用常数级额外空间(除了输入链表的节点外)。

五、解决方案二:递归法

原理讲解

递归思想非常优美:

  • list1list2null,返回另一条。
  • 比较两链表头节点:
    • 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),递归调用栈深度最多等于节点总数。

六、总结

解法 优点 缺点 适用场景
迭代法 时间效率高;不占用额外栈空间 代码略冗长 大多数实际业务逻辑中推荐使用
递归法 代码简洁美观;逻辑清晰 可能导致栈溢出 递归深度较小的场景,或用于教学演示
相关推荐
小O的算法实验室15 小时前
2026年ASOC,基于深度强化学习的无人机三维复杂环境分层自适应导航规划方法,深度解析+性能实测
算法·无人机·论文复现·智能算法·智能算法改进
郭涤生16 小时前
STL vector 扩容机制与自定义内存分配器设计分析
c++·算法
༾冬瓜大侠༿16 小时前
vector
c语言·开发语言·数据结构·c++·算法
Ricky111zzz16 小时前
leetcode学python记录1
python·算法·leetcode·职场和发展
汀、人工智能16 小时前
[特殊字符] 第58课:两个正序数组的中位数
数据结构·算法·数据库架构··数据流·两个正序数组的中位数
liu****16 小时前
第16届省赛蓝桥杯大赛C/C++大学B组(京津冀)
开发语言·数据结构·c++·算法·蓝桥杯
汀、人工智能17 小时前
[特殊字符] 第79课:分割等和子集
数据结构·算法·数据库架构·位运算·哈希表·分割等和子集
汀、人工智能17 小时前
[特殊字符] 第74课:完全平方数
数据结构·算法·数据库架构·图论·bfs·完全平方数
CoderCodingNo17 小时前
【GESP】C++四、五级练习题 luogu-P1177 【模板】排序
数据结构·c++·算法
Proxy_ZZ017 小时前
从零实现LDPC比特翻转译码器:C语言实战与底层逻辑解析
c语言·算法