链表题解——合并两个有序链表【LeetCode】

算法思路

这段代码使用双指针 + 哨兵节点的方法合并两个有序链表。具体步骤如下:

初始化哨兵节点:

  • 创建一个哨兵节点 dummy,用于简化链表操作,避免处理头节点的特殊情况

  • 使用指针 cur 指向 dummy,用于构建新的链表

遍历两个链表:

  • 使用 while list1 and list2 循环遍历两个链表,比较当前节点的值:

    • 如果 list1.val < list2.val,将 list1 节点连接到 cur 的后面,并移动 list1 指针

    • 否则,将 list2 节点连接到 cur 的后面,并移动 list2 指针

  • 每次连接一个节点后,移动 cur 指针到新连接的节点

处理剩余部分:

  • 当其中一个链表遍历完毕后,将另一个链表的剩余部分直接连接到 cur 的后面

返回结果:

  • 返回 dummy.next,即合并后的链表的头节点

时间复杂度分析

  • 最坏情况: O(m + n)

    • 需要遍历两个链表的全部节点,假设两个链表的长度分别为 m 和 n
  • 最好情况: O(min(m, n))

    • 当其中一个链表的所有元素都小于另一个链表时,只需遍历到较短链表结束
  • 平均情况: O(m + n)

空间复杂度分析

  • 额外空间: O(1)

    • 只使用了常数级别的额外空间(哨兵节点 dummy 和指针 cur
  • 原地修改:

    • 代码直接修改了输入链表的指针,没有创建新的链表节点

    • 实际上是将两个链表的节点重新连接,而不是复制

python 复制代码
class Solution(object):
    def mergeTwoLists(self, list1, list2):
        # 创建哨兵节点,简化边界处理
        dummy = ListNode(0)
        cur = dummy  # cur指针用于构建新链表
        
        # 当两个链表都不为空时,进行比较合并
        while list1 and list2:
            if list1.val < list2.val:
                cur.next = list1    # 将较小的节点连接到结果链表
                list1 = list1.next  # 移动list1指针
            else:
                cur.next = list2    # 将较小的节点连接到结果链表
                list2 = list2.next  # 移动list2指针
            cur = cur.next          # 移动cur指针到新添加的节点
        
        # 将剩余的链表部分直接连接(因为原链表已有序)
        cur.next = list1 if list1 else list2
        
        # 返回合并后链表的头节点(跳过哨兵节点)
        return dummy.next