发布于个人公众号,打开微信,搜索
MelodyJerry
即可
2. 两数相加
难度 | 中等 | 通过率 | 40.51% (909,450/2,244,760) |
---|
给你两个 非空
的链表,表示两个非负的整数。它们每位数字都是按照 逆序
的方式存储的,并且每个节点只能存储 一位
数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 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 - 题目数据保证列表表示的数字不含前导零
题解
这题目有几个关键点:
- 并没说明两个链表的长度是一样长的;
- 每位数字都是按照
逆序
的方式存储的 - 每个节点只能存储
一位
数字 - 以相同形式返回一个表示和的链表
- 列表表示的数字不含前导零
如上述,只需要将链表长度统一后再考虑是否进位即可:
- 长链的长度为
m
,短链的长度为n
,仅需要将短链结尾后的m-n
位置为0
。换句话说,即若当前节点!=null
,则取节点的val
;若==null
,则取0
。 - 维护
进位数
,该进位数
①用以记录当前位置两数求和后是否进位
,即求和后的数的十位数
,要么为0
,要么为1
;②该进位数需要参与在下一位置的求和计算中,即要么+0
,要么+1
。 - 计算完后,更新结果链表
answer
,且需要后移链表answer
、l1
、l2
的指针。 - 全部计算完成后,返回节点
answer.next
。
时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( n ) O(n) O(n)
上述代码有两个关键点:
- Q:为什么返回的是
answer.next
,而不是answer
?
- A:①在创建链表
answer
时,事先是不能知道要创建多长的链表;②在每一个位置的计算后都是new
一个ListNode sumNode
,并都是answer.next
指向sumNode
;③所以上述看来,链表answer
的头节点是null
,头节点的.next
才是预期结果的开始。
【注意点】
对于链表问题,返回结果为头结点
head
或head.next
时,通常需要先初始化一个预指针cur
,目的在于链表初始化时无可用节点值,而且链表构造过程需要移动指针,进而会导致头指针丢失、链表断裂,无法返回正确的链表。
- 为什么
while
中要进行carryNumber!=0
的判断?
- 看到代码末尾的注释中的测试用例后,应该能够理解,这里画个图,更好理解: