题目
给出两个非空的链表用来表示两个非负的整数。
其中,它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储一位数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字0之外,这两个数都不会以0开头。
示例
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
代码示例
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
}
思路
从今天开始就要开始打卡链表啦!
与数组很长的区别就是,我在测试的时候不能直接通过声明就拿到一个链表,需要自己实现。
很久没写过链表的代码,上来也是有点懵,但是别气馁。
把这个问题进行拆解,第一步,构造链表;第二步,再解题。
哈哈哈,就是这么简单。
先是找度娘看看现成的用golang实现链表的方案,此处贴上(studygolang.com/articles/17…)。
他是从头到尾创建的,但咱们这道题,已经给了node的结构定义,所以就不适用了,自己动手丰衣足食!
边看边想,自己想要的初始化,就写出来了 => 从后往前,这不就解决了!
接着这个思想对咱们这道题也是使用的,我们先遍历计算出每一位上数字和,放进数组中,最后再对数组初始化不能OK了吗!
代码
// 节点
type ListNode struct {
Val int
Next *ListNode
}
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
if l1 == nil {
return l2
}
if l2 == nil {
return l1
}
var sums []int
sum := 0
carry := 0
for l1 != nil && l2 != nil {
sum, carry = add(l1.Val, l2.Val+carry)
fmt.Println("sum: ", sum)
sums = append(sums, sum)
l1 = l1.Next
l2 = l2.Next
}
for l1 != nil {
sum, carry = add(l1.Val, carry)
fmt.Println("sum: ", sum)
sums = append(sums, sum)
l1 = l1.Next
}
for l2 != nil {
sum, carry = add(l2.Val, carry)
fmt.Println("sum: ", sum)
sums = append(sums, sum)
l2 = l2.Next
}
if carry != 0 {
fmt.Println("sum: ", carry)
sums = append(sums, carry)
}
var ret *ListNode
for i := len(sums) - 1; i >= 0; i-- {
node := &ListNode{
Val: sums[i],
Next: nil,
}
ret = Append(ret, node)
}
return ret
}
func add(a, b int) (ret, carry int) {
sum := a + b
sumArr := fmt.Sprintf("%d", sum)
if len(sumArr) > 1 {
ret, _ = strconv.Atoi(sumArr[1:])
carry, _ = strconv.Atoi(sumArr[:1])
} else {
ret = sum
carry = 0
}
return
}
func Append(list, node *ListNode) *ListNode {
if list == nil {
return node
}
node.Next = list
return node
}
测试
func main() {
nums1 := []int{2, 4, 3}
var list1 *ListNode
for i := len(nums1) - 1; i >= 0; i-- {
node := &ListNode{
Val: nums1[i],
Next: nil,
}
list1 = Append(list1, node)
}
fmt.Println(list1)
nums2 := []int{5, 6, 4}
var list2 *ListNode
for i := len(nums2) - 1; i >= 0; i-- {
node := &ListNode{
Val: nums2[i],
Next: nil,
}
list2 = Append(list2, node)
}
fmt.Println(list2)
// 等长两数组求和
ret := addTwoNumbers(list1, list2)
fmt.Println(ret)
nums3 := []int{9, 8}
var list3 *ListNode
for i := len(nums3) - 1; i >= 0; i-- {
node := &ListNode{
Val: nums3[i],
Next: nil,
}
list3 = Append(list3, node)
}
fmt.Println(list3)
nums4 := []int{1}
var list4 *ListNode
for i := len(nums4) - 1; i >= 0; i-- {
node := &ListNode{
Val: nums4[i],
Next: nil,
}
list4 = Append(list4, node)
}
fmt.Println(list4)
// 一长一短数组求和
ret = addTwoNumbers(list3, list4)
fmt.Println(ret)
}
结果如下:

分析
时间复杂度:O(max(len(nums1), len(nums2)))
空间复杂度:O(max(len(nums1), len(nums2)))