2. 两数相加
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。 请你将两个数相加,并以相同形式返回一个表示和的链表。 你可以假设除了数字 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- 题目数据保证列表表示的数字不含前导零
思路
这个题类似于大数加法。如果对应位置p,q的数分别是a,b的话,对应位置的加操作其实应该还加上一位的进位值d。接下来我们举个例子,就明白了。
对于当前对应位置,是第一个位置,我们可以当做之前的进位是
0,接下来进行相加
7+4+0。下一次的进位d=(a+b+d)%10。当前位置应该得到的值是v=(a+b+d)/10
我们新建一个链表,将v插入到链表尾部即可
重复上述步骤,直至p、q都为空。在遍历两个链表中,可能存在其中一个已经遍历到尾部了。我们采取的办法是先让a、b都等于0,对应位置指针不为空,才给a、b赋真正的值。
最后需要注意的是,如果两个链表都到尾部了,此时的加操作已经完毕。我们还需要判断进位是不是0,如果不是零的话需要将进位的值单独加到链表尾部。
代码
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
head := &ListNode{}
end := head
d := 0
p := l1
q := l2
for p != nil || q != nil{
// 先让a, b 等于0
a, b := 0, 0
// 对应位置不为空,才真正给a赋值
if p != nil {
a = p.Val
p = p.Next
}
// 对应位置不为空,才真正给b赋值
if q != nil {
b = q.Val
q = q.Next
}
// 当前位置的值
v := (a + b + d) % 10
// 下一位置的进位值
d = (a + b + d) / 10
node := &ListNode{
Val: v,
}
end.Next = node
end = node
}
// 判断进位只不是0,不是0的话需要新建一个节点,插入进去
if d != 0 {
node := &ListNode{
Val: d,
}
end.Next = node
end = node
}
return head.Next
}