leetcode 21 合并两个有序链表
问题描述
LeetCode 21 题要求将两个升序排列的链表合并为一个新的升序链表。合并后的链表应通过拼接原链表的节点完成,而非创建新节点。
解题思路
递归法
看这个评论区的图解,便于理解
https://leetcode.cn/problems/merge-two-sorted-lists/solutions/103891/yi-kan-jiu-hui-yi-xie-jiu-fei-xiang-jie-di-gui-by-
- 比较两个链表当前节点的值,将较小节点作为合并后链表的头节点。
- 递归调用函数处理剩余部分,将较小节点的
next
指向递归结果。 - 终止条件:任一链表为空时,直接返回另一链表。
迭代法
迭代法的具体思路就是哪个节点的值更小,则将新的链表的next连给他,问题是新链表的头节点可能是l1或者l2,不确定,解决的方法是新建一个头节点,最后返回的时候返回他的next
- 创建一个虚拟头节点
dummy
和指针current
指向它。 - 遍历两个链表,每次将较小的节点连接到
current
后,并移动对应链表的指针。 - 当某一链表遍历完成后,将
current
的next
指向剩余链表。
代码实现
递归法 Python 示例
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:if list1 is None:return list2if list2 is None:return list1if list1.val <= list2.val:list1.next = self.mergeTwoLists(list1.next,list2)return list1else:list2.next = self.mergeTwoLists(list1,list2.next)return list2
迭代法 Python 示例
class Solution:def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:# 首先采用哨兵解法,构造一个伪头节点dummy = cur = ListNode(0)while list1 and list2:if list1.val <= list2.val:cur.next = list1list1 = list1.nextelse:cur.next = list2list2 = list2.nextcur = cur.nextcur.next = list1 if list1 else list2return dummy.next
复杂度分析
- 时间复杂度:O(m+n),其中 m 和 n 分别为两个链表的长度。
- 空间复杂度:
- 递归法:O(m+n),栈空间取决于递归深度。
- 迭代法:O(1),仅使用常数级额外空间。
边界条件
- 其中一个链表为空时,直接返回另一链表。
- 两个链表均为空时,返回空。
扩展思考
- 如何合并 K 个有序链表?(LeetCode 23 题)
- 如果链表为降序排列,如何调整代码?
- 如何处理链表中的重复值?