LeetCode 热题100 2. 两数相加
LeetCode 热题100 | 2. 两数相加
大家好,今天我们来解决一道经典的算法题——两数相加。这道题在 LeetCode 上被标记为中等难度,要求我们将两个非空的链表表示的整数相加,并以相同形式返回一个表示和的链表。下面我将详细讲解解题思路,并附上 Python 代码实现。
题目描述
给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。请你将两个数相加,并以相同形式返回一个表示和的链表。
示例:
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807。
解题思路
这道题的核心是模拟两个数的加法过程。由于链表是逆序存储的,我们可以直接从链表的头部开始逐位相加,并处理进位。
核心思想
-
初始化:
- 创建一个虚拟头节点
dummy
,用于简化链表操作。 - 使用一个指针
current
指向当前节点。 - 初始化进位
carry
为 0。
- 创建一个虚拟头节点
-
遍历链表:
- 遍历两个链表,逐位相加,并加上进位。
- 计算当前位的值
sum_val
和新的进位carry
。 - 创建一个新节点,存储
sum_val % 10
,并将其链接到结果链表中。 - 移动指针
current
和链表指针l1
、l2
。
-
处理剩余的进位:
- 如果遍历结束后仍有进位,创建一个新节点存储进位。
-
返回结果:
- 返回虚拟头节点的下一个节点,即结果链表的头节点。
代码实现
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def addTwoNumbers(l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
dummy = ListNode() # 虚拟头节点
current = dummy # 当前节点指针
carry = 0 # 进位
# 遍历两个链表
while l1 or l2 or carry:
# 计算当前位的值
val1 = l1.val if l1 else 0
val2 = l2.val if l2 else 0
sum_val = val1 + val2 + carry
carry = sum_val // 10 # 计算进位
current.next = ListNode(sum_val % 10) # 创建新节点
current = current.next # 移动指针
# 移动链表指针
if l1:
l1 = l1.next
if l2:
l2 = l2.next
return dummy.next # 返回结果链表的头节点
代码解析
-
初始化:
dummy
是虚拟头节点,用于简化链表操作。current
指向当前节点,初始时指向dummy
。carry
是进位,初始为 0。
-
遍历链表:
- 使用
while
循环遍历两个链表,直到两个链表都遍历完且没有进位。 - 计算当前位的值
sum_val
和新的进位carry
。 - 创建一个新节点,存储
sum_val % 10
,并将其链接到结果链表中。 - 移动指针
current
和链表指针l1
、l2
。
- 使用
-
处理剩余的进位:
- 如果遍历结束后仍有进位,创建一个新节点存储进位。
-
返回结果:
- 返回
dummy.next
,即结果链表的头节点。
- 返回
复杂度分析
- 时间复杂度:O(max(m, n)),其中 m 和 n 分别是两个链表的长度。我们需要遍历两个链表的所有节点。
- 空间复杂度:O(max(m, n)),结果链表的长度最多为 max(m, n) + 1。
示例运行
示例 1
# 创建链表 l1 = [2,4,3]
l1 = ListNode(2)
l1.next = ListNode(4)
l1.next.next = ListNode(3)
# 创建链表 l2 = [5,6,4]
l2 = ListNode(5)
l2.next = ListNode(6)
l2.next.next = ListNode(4)
# 计算两数相加
result = addTwoNumbers(l1, l2)
# 输出结果链表
while result:
print(result.val, end=" -> ")
result = result.next
print("None")
输出:
7 -> 0 -> 8 -> None
示例 2
# 创建链表 l1 = [0]
l1 = ListNode(0)
# 创建链表 l2 = [0]
l2 = ListNode(0)
# 计算两数相加
result = addTwoNumbers(l1, l2)
# 输出结果链表
while result:
print(result.val, end=" -> ")
result = result.next
print("None")
输出:
0 -> None
示例 3
# 创建链表 l1 = [9,9,9,9,9,9,9]
l1 = ListNode(9)
l1.next = ListNode(9)
l1.next.next = ListNode(9)
l1.next.next.next = ListNode(9)
l1.next.next.next.next = ListNode(9)
l1.next.next.next.next.next = ListNode(9)
l1.next.next.next.next.next.next = ListNode(9)
# 创建链表 l2 = [9,9,9,9]
l2 = ListNode(9)
l2.next = ListNode(9)
l2.next.next = ListNode(9)
l2.next.next.next = ListNode(9)
# 计算两数相加
result = addTwoNumbers(l1, l2)
# 输出结果链表
while result:
print(result.val, end=" -> ")
result = result.next
print("None")
输出:
8 -> 9 -> 9 -> 9 -> 0 -> 0 -> 0 -> 1 -> None
总结
通过模拟加法过程,我们可以高效地将两个链表表示的整数相加,并返回结果链表。这种方法的时间复杂度为 O(max(m, n)),空间复杂度为 O(max(m, n)),能够处理较大的输入规模。希望这篇题解对你有帮助!如果还有其他问题,欢迎继续提问!
关注我,获取更多算法题解和编程技巧!