Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
题目描述:
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 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
题目数据保证列表表示的数字不含前导零
思路分析:
该题主要是对应位置的各结点相加后,产生的进位需要在下一位置的结点相加时也加上。
所以需要用一个变量来保存产生的进位。
另外最后的结点相加产生进位时,也需要再添加一个新结点保存进位的值。
实现逻辑:
- 定义两个变量分别指向两个链表结点的开头。
- 同一层结点的值进行加法运算,进位的值保存到内部变量,为下一层结点加法运算使用。
如果其中一个结点为空,则另外一个结点和进位的值进行加法运算。
如果两个结点都为空,则结果是进位的值。 - 加法运算后的个位数保存到结点的值中,然后开始定义的变量分别指向下一层结点。
- 重复直到下层结点都为空或没有产生进位。
AC 代码:
golang :
链表节点定义:
// ListNode 链表节点
type ListNode struct {
Val int
Next *ListNode
}
两数相加:
// 2. 两数相加
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
var node ListNode
nTmp := &node
nTmp1 := l1
nTmp2 := l2
// 保存加法进位的值
dec := 0
for nTmp1 != nil || nTmp2 != nil || dec == 1 {
var node ListNode
// 同一层的节点进行加法运算
tmp := 0
if nTmp1 != nil && nTmp2 != nil {
tmp = nTmp1.Val + nTmp2.Val + dec
} else if nTmp1 != nil {
tmp = nTmp1.Val + dec
} else if nTmp2 != nil {
tmp = nTmp2.Val + dec
} else {
tmp = dec
}
// 当前节点的值
node.Val = tmp % 10
nTmp.Next = &node
nTmp = &node
// 进位的值
dec = tmp / 10
// 循环条件,最后一位进位时,dec 置为 0
if nTmp1 == nil && nTmp2 == nil && dec == 1 {
dec = 0
}
// 指向下一个节点
if nTmp1 != nil {
nTmp1 = nTmp1.Next
}
// 指向下一个节点
if nTmp2 != nil {
nTmp2 = nTmp2.Next
}
}
return node.Next
}
测试:
func main() {
// [1,9,9,9]
var l1 ListNode
l1.Val = 1
nTmp1 := &l1
for i := 0; i < 3; i++ {
var node ListNode
node.Val = 9
nTmp1.Next = &node
nTmp1 = &node
}
// [2,9,9]
var l2 ListNode
l2.Val = 2
nTmp2 := &l2
for i := 0; i < 2; i++ {
var node ListNode
node.Val = 9
nTmp2.Next = &node
nTmp2 = &node
}
// [3,8,9,0,1]
// 9991 + 992 = 10983
result := addTwoNumbers(&l1, &l2)
fmt.Println(result)
}
总结:
该问题主要的点是进位的处理和最后一位加法运算后产生进位的处理。
加法运算的进位要保留到下一层节点的运算。