0002 两数相加/Add Two Numbers
题目描述/Description
给出两个非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储一位数字。 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字 0 之外,这两个数都不会以 0开头。
You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.You may assume the two numbers do not contain any leading zero, except the number 0 itself.
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/ad… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
示例
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
- 思路1
保存进位数据迭代时与链表数据相加
代码实现
package kit
import "fmt"
type ListNode struct {
Val int
Next *ListNode
}
func List2Ints(head *ListNode) []int {
limit := 100
times := 0
res := []int{}
for head != nil {
times++
if times > limit {
msg := fmt.Sprintf("链条深度超过%d,可能出现环状链条。请检查错误,或者放宽 l2s 函数中 limit 的限制。", limit)
panic(msg)
}
res = append(res, head.Val)
head = head.Next
}
return res
}
func Ints2List(nums []int) *ListNode {
h := new(ListNode)
t := h
for _, v := range nums {
t.Next = &ListNode{Val: v}
t = t.Next
}
return h.Next
}
func (l *ListNode) GetNodeWith(Val int) *ListNode {
t := l
for t != nil {
if t.Val == Val {
break
}
t = t.Next
}
return t
}
func Ints2ListWithCycle(nums []int, pos int) *ListNode {
h := Ints2List(nums)
if pos == -1 {
return h
}
c := h
for pos > 0 {
c = c.Next
pos--
}
t := c
for t.Next != nil {
t = t.Next
}
t.Next = c
return h
}
package problem0002
import (
"kit"
)
type ListNode = kit.ListNode
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
resPre := &ListNode{}
cur := resPre
carry := 0
for l1 != nil || l2 != nil || carry > 0 {
sum := carry
if l1 != nil {
sum += l1.Val
l1 = l1.Next
}
if l2 != nil {
sum += l2.Val
l2 = l2.Next
}
carry = sum / 10
cur.Next = &ListNode{Val: sum % 10}
cur = cur.Next
}
return resPre.Next
}
单元测试
package kit
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestList2Ints(t *testing.T) {
ast := assert.New(t)
ast.Equal([]int{}, List2Ints(nil), "输入nil,没有返回[]int{}")
one2three := &ListNode{
Val: 1,
Next: &ListNode{
Val: 2,
Next: &ListNode{
Val: 3,
},
},
}
ast.Equal([]int{1, 2, 3}, List2Ints(one2three), "没有成功地转换成[]int")
limit := 100
overLimitList := Ints2List(make([]int, limit+1))
ast.Panics(func() { List2Ints(overLimitList) }, "转换深度超过 %d 限制的链条,没有 panic", limit)
}
func TestInts2List(t *testing.T) {
ast := assert.New(t)
ast.Nil(Ints2List([]int{}), "输入[]int{},没有返回nil")
ln := Ints2List([]int{1, 2, 3, 4, 5, 6, 7, 8, 9})
i := 1
for ln != nil {
ast.Equal(i, ln.Val, "对应的值不对")
ln = ln.Next
i++
}
}
func TestGetNodeWith(t *testing.T) {
ast := assert.New(t)
//
ln := Ints2List([]int{1, 2, 3, 4, 5, 6, 7, 8, 9})
val := 10
node := &ListNode{
Val: val,
}
tail := ln
for tail.Next != nil {
tail = tail.Next
}
tail.Next = node
expected := node
actual := ln.GetNodeWith(val)
ast.Equal(expected, actual)
}
func TestInts2ListWithCycle(t *testing.T) {
ast := assert.New(t)
ints := []int{1, 2, 3}
l := Ints2ListWithCycle(ints, -1)
ast.Equal(ints, List2Ints(l))
l = Ints2ListWithCycle(ints, 1)
ast.Panics(func() { List2Ints(l) })
}
package problem0002
import (
"kit"
"testing"
"github.com/stretchr/testify/assert"
)
type para struct {
one *ListNode
two *ListNode
}
type ans struct {
one *ListNode
}
type question struct {
p para
a ans
}
func TestAddTwoNumbers(t *testing.T) {
ast := assert.New(t)
qs := []question{
question{
p: para{
one: kit.Ints2List([]int{2, 4, 3}),
two: kit.Ints2List([]int{5, 6, 4}),
},
a: ans{
one: kit.Ints2List([]int{7, 0, 8}),
},
},
question{
p: para{
one: kit.Ints2List([]int{9, 8, 7, 6, 5}),
two: kit.Ints2List([]int{1, 1, 2, 3, 4}),
},
a: ans{
one: kit.Ints2List([]int{0, 0, 0, 0, 0, 1}),
},
},
question{
p: para{
one: kit.Ints2List([]int{0}),
two: kit.Ints2List([]int{5, 6, 4}),
},
a: ans{
one: kit.Ints2List([]int{5, 6, 4}),
},
},
}
for _, q := range qs {
a, p := q.a, q.p
ast.Equal(a.one, addTwoNumbers(p.one, p.two), "输入:%v", p)
}
}