【Golang 刷题之路】转世重修第二题:两数相加
Golang轻松学习一、两数相加?
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 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]
来源:力扣(LeetCode)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、详细代码
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链表的第一题,在不熟悉指针的时候,链表是最让人头疼的地方,绕来绕去傻傻分不清楚,希望看到博文的你能够摆脱我的苦恼,成为一个熟知链表熟悉指针的人,我们的学习之路开始启程,路途遥远,只求风雨兼程。
希望这个博客能对你有所益处。我是轻王,我为自己代言。