返回
路飞通关 LeetCode 23:合并 K 个升序链表,四两拨千斤的合并术
前端
2023-11-13 04:37:14
在算法的世界里,链表是一种常见的数据结构,它由一系列节点组成,每个节点包含一个值和指向下一个节点的指针。LeetCode 23 题正是围绕链表合并展开,要求我们把 K 个已经按升序排列的链表合并成一个升序链表。
乍一看,合并链表似乎是一项繁琐的任务,但别担心!路飞将为你揭秘多路归并算法的奥秘,让你轻松搞定这个难题。
多路归并算法
多路归并算法是合并多个有序序列的经典算法。其核心思想是,将序列逐一对半分,然后依次合并,直到所有序列都合并为一个。
在我们的链表合并问题中,我们可以将 K 个链表看作 K 个有序序列。算法步骤如下:
- 递归分治: 将 K 个链表分成两组,每一组包含 K/2 个链表。对每组链表递归地应用多路归并算法。
- 合并两组: 将分治后得到的两组有序链表合并为一个有序链表。
- 重复步骤 1 和 2: 继续递归分治和合并,直到所有链表都被合并为一个。
代码实现
有了多路归并算法的指导,我们就可以用代码来实现链表合并。以 Python 为例,代码如下:
def mergeKLists(lists):
"""
:type lists: List[ListNode]
:rtype: ListNode
"""
if not lists:
return None
# 递归基准条件:只有一个链表时,直接返回
if len(lists) == 1:
return lists[0]
# 将链表分成两组
mid = len(lists) // 2
left = mergeKLists(lists[:mid])
right = mergeKLists(lists[mid:])
# 合并两组链表
return mergeTwoLists(left, right)
def mergeTwoLists(l1, l2):
"""
合并两个有序链表
"""
dummy = ListNode(0)
curr = dummy
while l1 and l2:
if l1.val < l2.val:
curr.next = l1
l1 = l1.next
else:
curr.next = l2
l2 = l2.next
curr = curr.next
if l1:
curr.next = l1
if l2:
curr.next = l2
return dummy.next
LeetCode 原题示例
LeetCode 23 给出了一个包含四个升序链表的示例,如下:
[
1->4->5,
1->3->4,
2->6
]
按照多路归并算法的步骤,我们将这些链表合并为一个升序链表:
-
将链表分成两组:
- 第 1 组:1->4->5, 1->3->4
- 第 2 组:2->6
-
分别合并两组:
- 第 1 组:1->3->4->4->5
- 第 2 组:2->6
-
合并两组:
- 1->3->4->4->5, 2->6
- 最终合并后的升序链表:1->2->3->4->4->5->6
总结
通过这篇文章,你已经了解了如何使用多路归并算法合并 K 个升序链表。掌握了这种技术,你将能够轻松应对 LeetCode 23 题和其他类似的链表合并问题。
记住,算法的本质在于分而治之,将复杂问题分解成更小的子问题,逐步解决。多路归并算法正是这种思想的完美体现。
希望这篇文章对你有所帮助。如果你有其他问题或建议,欢迎随时留言。
致谢
感谢「2022首次更文挑战」活动的鼓励,让我有动力持续创作优质文章。期待未来与你分享更多精彩内容!