LeetCode题解-Go 0x0002 Add Two Numbers

534 阅读3分钟

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)
	}
}