合并两个有序链表

题目:

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

示例 2:

输入:l1 = [], l2 = []
输出:[]

示例 3:

输入:l1 = [], l2 = [0]
输出:[0]

提示:

  • 两个链表的节点数目范围是 [0, 50]
  • -100 <= Node.val <= 100
  • l1 和 l2 均按 非递减顺序 排列

非递归方法(迭代)

思路:

利用迭代的方式合并两个有序链表。我们可以维护一个新的头节点 dummy,以及一个指针 current 指向当前合并后的链表的末尾。然后,比较两个链表的头节点,将较小的节点接入到新链表中,并更新相应的指针,直到其中一个链表为空。最后,将剩余非空的链表直接接入到新链表的末尾。

实现步骤:
  1. 初始化一个 dummy 节点作为新链表的头部。
  2. 使用 current 指针来表示当前合并后链表的最后一个节点。
  3. 遍历两个链表,比较当前节点的值,将较小的节点接入到新链表中,并移动相应的指针。
  4. 将剩余非空的链表直接接入到新链表的末尾。
  5. 返回 dummy.next,即合并后的链表的头节点。
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    ListNode dummy = new ListNode(-1);
    ListNode current = dummy;
    
    while (l1 != null && l2 != null) {
        if (l1.val <= l2.val) {
            current.next = l1;
            l1 = l1.next;
        } else {
            current.next = l2;
            l2 = l2.next;
        }
        current = current.next;
    }
    
    // 将剩余部分接到新链表的末尾
    current.next = (l1 != null) ? l1 : l2;
    
    return dummy.next;
}
复杂度分析:
  • 时间复杂度:O(n),其中 n 是两个链表中节点总数的较小值。因为每个节点只会被访问一次。
  • 空间复杂度:O(1),除了存储合并后的链表之外,只使用了常量级的额外空间。
 

递归方法

思路:

递归的思路是比较两个链表的头节点,将较小的头节点作为当前节点的下一个节点,并递归地处理剩余的部分。递归函数可以定义为:

  • 如果其中一个链表为空,直接返回另一个链表。
  • 否则,比较两个链表的头节点,将较小的节点的 next 指向递归合并后的结果。
实现步骤:
  1. 如果 l1 为空,返回 l2;如果 l2 为空,返回 l1。
  2. 比较 l1 和 l2 的头节点,将较小节点的 next 指向递归合并后的结果。
  3. 返回较小节点作为当前递归层的头节点。
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    if (l1 == null) {
        return l2;
    }
    if (l2 == null) {
        return l1;
    }
    
    if (l1.val <= l2.val) {
        l1.next = mergeTwoLists(l1.next, l2);
        return l1;
    } else {
        l2.next = mergeTwoLists(l1, l2.next);
        return l2;
    }
}
复杂度分析:
  • 时间复杂度:O(n),其中 n 是两个链表中节点总数的较小值。因为每个节点只会被访问一次。
  • 空间复杂度:O(n),递归调用的栈空间。在最坏情况下,递归深度可以达到 n。

这两种方法都可以有效地合并两个有序链表,并返回一个新的有序链表。选择使用迭代方法还是递归方法取决于个人偏好和具体的应用场景,但从效率上来说,迭代方法通常更具有优势。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无知、508

你的鼓励实我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值