文章目录
- 问题描述
- 示例1
- 示例2
- 示例 3
- 提示
- 思路分析
- 代码分析
- 完整代码
- 详细分析
- 完结
问题描述
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例1
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
示例2
输入:l1 = [0], l2 = [0]
输出:[0]
示例 3
输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]
提示
- 每个链表中的节点数在范围 [1, 100] 内
- 0 <= Node.val <= 9
- 题目数据保证列表表示的数字不含前导零
思路分析
-
首先,检查特殊情况。如果其中一个链表为空,直接返回另一个链表。这是为了处理其中一个链表为空的边界情况。
-
然后,创建一个哑结点(dummy)作为结果链表的头节点,并创建一个当前节点指针(curr)用于逐个链接新的节点。
-
接下来,需要考虑进位问题。创建一个变量carry,用于记录当前的进位值,初始值为0。
-
然后,开始遍历两个链表,同时处理进位。遍历过程中,我们需要同时访问两个链表的当前节点,并将其值加上进位值,得到一个新的节点值。如果某个链表已经遍历完了,我们可以将其缺失的位数视为0。
-
在每一位数字相加后,需要更新carry变量。当两个数的和超过9时,carry等于1,否则carry等于0。我们可以使用除法运算符和取模运算符进行计算。
-
将新的节点插入结果链表中,并将当前节点指针后移一位。注意,我们需要使用"curr.next"来链接新的节点,并将当前节点指针更新为新的节点。
-
继续遍历两个链表,直到其中一个链表遍历完或者两个链表都遍历完为止。这样可以确保将两个链表的所有位数都相加到结果链表中。
-
检查是否还有进位需要处理。如果carry大于0,说明还有进位,需要将其作为新的节点添加到结果链表的末尾。
-
最后,返回结果链表的头节点(dummy.next),即可得到表示和的链表。
-
通过遍历两个逆序链表,逐位相加,并处理进位问题,实现了将两个非负整数相加的功能。
代码分析
class Solution(object):
def addTwoNumbers(self, l1, l2):
if not l1:
return l2
if not l2:
return l1
dummy = ListNode(0)
这行代码定义了一个名为dummy
的哑结点,用于表示结果链表的头节点。
curr = dummy
这行代码将curr
指针指向哑结点,作为当前节点的指针。
carry = 0
这行代码初始化进位值为0。
while l1 or l2:
x = l1.val if l1 else 0
y = l2.val if l2 else 0
sum = x + y + carry
carry = sum // 10
curr.next = ListNode(sum % 10)
curr = curr.next
if l1:
l1 = l1.next
if l2:
l2 = l2.next
这段代码使用了循环来遍历两个链表并进行相加。在每一次循环中,根据当前节点是否为空,获取当前节点的值,并处理链表已经遍历完的情况。接着,计算当前位置的两个节点值以及进位的和,并更新进位值。然后,创建新的节点,并将其链接到当前节点的下一个,将当前节点指针后移一位,指向新创建的节点。最后,如果链表还未遍历完,将当前节点指针后移一位。
if carry > 0:
curr.next = ListNode(carry)
这行代码处理最后的进位,如果最后还有进位,创建新的节点并将其链接到结果链表的末尾。
return dummy.next
这行代码返回结果链表的头节点(dummy.next)。
完整代码
class Solution(object): # 定义一个Solution类,继承自object基类
def addTwoNumbers(self, l1, l2): # 定义一个addTwoNumbers方法,接受l1和l2两个参数
if not l1: # 如果l1为空链表,返回l2
return l2
if not l2: # 如果l2为空链表,返回l1
return l1
dummy = ListNode(0) # 创建一个值为0的哑结点,用于表示结果链表的头节点
curr = dummy # 将curr指针指向哑结点,用于逐个链接新的节点
carry = 0 # 初始化进位值为0
while l1 or l2: # 开始遍历两个链表,循环条件为两个链表中至少有一个未遍历完
x = l1.val if l1 else 0 # 获取当前节点l1的值,如果l1为空,则视为0
y = l2.val if l2 else 0 # 获取当前节点l2的值,如果l2为空,则视为0
sum = x + y + carry # 计算当前位置的两个节点值以及进位的和
carry = sum // 10 # 更新进位值,如果和大于等于10,则进位为1;否则进位为0
curr.next = ListNode(sum % 10) # 创建新的节点,并将其链接到当前节点的下一个
curr = curr.next # 将当前节点指针后移一位,指向新创建的节点
if l1: # 如果l1还未遍历完,将当前节点指针后移一位
l1 = l1.next
if l2: # 如果l2还未遍历完,将当前节点指针后移一位
l2 = l2.next
if carry > 0: # 如果最后还有进位,创建新的节点并将其链接到结果链表的末尾
curr.next = ListNode(carry)
return dummy.next # 返回结果链表的头节点(dummy.next)
详细分析
-
class Solution(object):
:定义了一个名为Solution
的类,继承自object
。 -
def addTwoNumbers(self, l1, l2):
:定义了一个名为addTwoNumbers
的方法,它接受self
(表示当前对象)以及两个参数l1
和l2
(两个链表)。 -
"""
和"""
之间的内容是方法的文档字符串,用于描述方法的功能和参数。 -
if not l1: return l2
和if not l2: return l1
:检查特殊情况。如果其中一个链表为空,直接返回另一个链表作为结果。 -
dummy = ListNode(0)
:创建一个值为0的哑结点,用于表示结果链表的头节点。 -
curr = dummy
:将curr
指针指向哑结点,用于逐个链接新的节点。 -
carry = 0
:初始化进位值为0。 -
while l1 or l2:
:开始遍历两个链表,循环条件为两个链表中至少有一个未遍历完。 -
x = l1.val if l1 else 0
和y = l2.val if l2 else 0
:获取当前节点的值,并处理链表已经遍历完的情况。如果链表已经遍历完,将当前节点的值视为0。 -
sum = x + y + carry
:计算当前位置的两个节点值以及进位的和。 -
carry = sum // 10
:更新进位值,如果和大于等于10,则进位为1;否则进位为0。 -
curr.next = ListNode(sum % 10)
:创建新的节点,并将其链接到当前节点的下一个。 -
curr = curr.next
:将当前节点指针后移一位,指向新创建的节点。 -
if l1: l1 = l1.next
和if l2: l2 = l2.next
:如果链表还未遍历完,将当前节点指针后移一位。 -
if carry > 0: curr.next = ListNode(carry)
:如果最后还有进位,创建新的节点并将其链接到结果链表的末尾。 -
return dummy.next
:返回结果链表的头节点(dummy.next)。