返回
极简攻略:LeetCode [21] 合并两个有序链表
闲谈
2023-09-07 00:53:06
前言
在LeetCode的广阔题海中,[21] 合并两个有序链表是一道经典题。它不仅考察了我们对链表的基本操作,还要求我们理解递归的思想。本文将带你从零入门,层层深入,透彻理解这道题目的精髓。
链表简介
链表是一种常见的数据结构,它由一系列相互连接的节点组成。每个节点包含两个部分:数据域和指针域。数据域存储数据,指针域存储下一个节点的地址。链表具有以下特点:
- 灵活性强: 链表可以根据需要动态地增加或删除节点,而无需重新分配内存。
- 插入和删除效率高: 在链表中插入或删除一个节点只需要改变指针,而不需要移动数据。
- 空间利用率低: 链表的每个节点都包含一个指针域,这会占用额外的空间。
递归的含义
递归是一种函数在运行时调用自身的方法。它通常用于解决那些具有自相似结构的问题。递归函数必须具有以下两个要素:
- 递归调用: 函数在运行时调用自身。
- 终止条件: 函数必须有一个或多个终止条件,否则它将无限地调用自身,导致程序崩溃。
升序链表的定义
升序链表是指一个链表中的元素从小到大排列。升序链表通常用于存储有序的数据,例如学生成绩、商品价格等。
合并两个有序链表
现在,我们已经掌握了链表、递归和升序链表的基础知识,就可以开始解决[21] 合并两个有序链表这道题了。
这道题的目的是将两个升序链表合并成一个新的升序链表。合并后的链表应该包含两个原链表的所有元素,并且元素仍然保持升序。
合并算法
我们可以使用递归来解决这道题。递归算法的步骤如下:
- 如果两个链表都为空,则返回一个空链表。
- 如果其中一个链表为空,则返回另一个链表。
- 比较两个链表的头节点的数据,较小的那个节点成为合并后链表的头节点。
- 将较小节点的下一个节点作为合并后链表的下一个节点,然后递归地合并剩下的两个链表。
终止条件
递归算法的终止条件是两个链表都为空。当两个链表都为空时,我们返回一个空链表,这将结束递归调用。
代码实现
def mergeTwoLists(l1, l2):
"""
合并两个升序链表
:param l1: 第一个链表
:param l2: 第二个链表
:return: 合并后的链表
"""
# 如果两个链表都为空,则返回一个空链表
if not l1 and not l2:
return None
# 如果其中一个链表为空,则返回另一个链表
if not l1:
return l2
if not l2:
return l1
# 比较两个链表的头节点的数据,较小的那个节点成为合并后链表的头节点
if l1.val < l2.val:
head = l1
l1 = l1.next
else:
head = l2
l2 = l2.next
# 将较小节点的下一个节点作为合并后链表的下一个节点,然后递归地合并剩下的两个链表
head.next = mergeTwoLists(l1, l2)
return head
总结
[21] 合并两个有序链表是一道经典的LeetCode题目。它考察了我们对链表的基本操作、递归的思想和升序链表的理解。通过本文的讲解,希望你能对这道题有更深入的认识。