二、详细代码给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
1.理清题目思路
- 要求是什么?我们需要将两个切片中的值相加
- 条件是什么?链表需依照十进制进行进位操作
- 优化是什么?依托于一个条件链表进行扩展,可以节省内存空间
2.代码思路,带注释
代码如下(示例):
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
// 命名一个用来记录头节点的 n
n := l1
var (
add int
val int
)
for {
// 每一个数都是两个数加上进位的数
val = l1.Val + l2.Val + add
// 用 % 排除进位
l1.Val = val % 10
// 用 / 找出是否进位
add = val / 10
// 若两个链表的下一个节点都为空
// 证明链表该节点为最终节点
if l1.Next == nil && l2.Next == nil {
// 若还有进位 添加一个新节点存储进位值
if add > 0 {
l1.Next = &ListNode{
Val: 1,
Next: nil,
}
}
break
}
// 若l1 比l2 短,将两个链表后续节点交换
if l1.Next == nil && l2.Next != nil {
l1.Next, l2.Next = l2.Next, l1.Next
}
// 若节点下一个已为空
// 设定一个空值继续进行操作
if l1.Next != nil {
l1 = l1.Next
} else {
l1 = &ListNode{}
}
if l2.Next != nil {
l2 = l2.Next
} else {
l2 = &ListNode{}
}
}
return n
}
2.理解题解中的优秀代码
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
var resultHead *ListNode // 空节点
var pre *ListNode // 空节点
overTen := 0 // 进位
// 当左右链表有值或进位有值
for l1 != nil || l2 != nil || overTen != 0 {
// 先加上进位
sum := overTen
if l1 != nil{
// 左链表存在加上当前节点的值,移到下一个链表
sum += l1.Val
l1 = l1.Next
}
if l2 != nil{
// 右链表存在加上当前节点的值,移到下一个链表
sum += l2.Val
l2 = l2.Next
}
// 新的节点来存放最终的值
current := &ListNode{
Val: 0,
Next: nil,
}
current.Val += sum
// 判断是否需要进 1
if current.Val >= 10{
current.Val = current.Val % 10
overTen = 1
}else {
overTen = 0
}
// 如果还没结束继续遍历
if pre != nil{
pre.Next = current
}else {
// 结束就丢进返回链表
resultHead = current
}
pre = current
}
return resultHead
}
结果
两数相加是Leetcode链表的第一题,在不熟悉指针的时候,链表是最让人头疼的地方,绕来绕去傻傻分不清楚,希望看到博文的你能够摆脱我的苦恼,成为一个熟知链表熟悉指针的人,我们的学习之路开始启程,路途遥远,只求风雨兼程。
希望这个博客能对你有所益处。我是轻王,我为自己代言。