原题
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 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]
提示:
每个链表中的节点数在范围 [1, 100] 内
0 <= Node.val <= 9
题目数据保证列表表示的数字不含前导零
解题
第一次尝试方法:
将两个链表的数据转换成两个整数,然后相加得到sum,再将sum拆分成链表返回
package main
import "fmt"
type ListNode struct {
Val int
Next *ListNode
}
/**
* 头插入数据 A ---> B->A ---> C->B->A
*/
func insert(head *ListNode, val int) *ListNode {
newList := new(ListNode)
newList.Val = val
newList.Next = head
return newList
}
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
//遍历链表 l1 获取num1
num1 := 0
var index int = 1
for l1 != nil {
num1 += l1.Val * index
l1 = l1.Next
index *= 10
}
fmt.Printf("num1: %v\n", num1)
//遍历链表 l2 获取num2
num2 := 0
var index2 int = 1
for l2 != nil {
num2 += l2.Val * index2
l2 = l2.Next
index2 *= 10
}
fmt.Printf("num2: %v\n", num2)
//两书相加
num := num1 + num2
fmt.Printf("num: %v\n", num)
//申请头结点
sumList := new(ListNode)
sumList.Next = nil
sumList.Val = 0
if num == 0 {
return sumList
}
tmpNum := num
for tmpNum != 0 {
//取个位数
val := tmpNum % 10
//去掉个位数
tmpNum = tmpNum / 10
//申请链表头(链表头不存储数据)
newList := new(ListNode)
newList.Val = val
newList.Next = nil
//遍历链表头,找到尾结点
tmpList := sumList
for tmpList.Next != nil {
tmpList = tmpList.Next
}
//将新节点尾部插入
tmpList.Next = newList
}
return sumList.Next
}
func main() {
/**
* 构造链表 3 ---> 4->3 ---> 2->4->3 342
*/
list1 := new(ListNode)
list1.Val = 3
list1.Next = nil
list1 = insert(list1, 4)
list1 = insert(list1, 2)
// list := list1
// for list != nil {
// fmt.Printf("list1.Val: %v\n", list.Val)
// list = list.Next
// }
/**
* 构造链表 4 ---> 6->4 ---> 5->6->4 465
*/
list2 := new(ListNode)
list2.Val = 4
list2.Next = nil
list2 = insert(list2, 6)
list2 = insert(list2, 5)
//两数相加求和 342+465=807 7->0->8
listNew := addTwoNumbers(list1, list2)
print("====================\n")
list := listNew
for list != nil {
fmt.Printf("list1.Val: %v\n", list.Val)
list = list.Next
}
}
想法还行,提交失败
未考虑大数相加,例如
输入:
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]
[5,6,4]
输出:
[2,8,0,4,6,2,5,0,3,0,7,2,4,4,9,6,7,0,5]
预期结果:
[6,6,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]
改进,直接对链表的数字相加进位,返回最长的链表
package main
import "fmt"
type ListNode struct {
Val int
Next *ListNode
}
/**
* 头插入数据 A ---> B->A ---> C->B->A
*/
func insert(head *ListNode, val int) *ListNode {
newList := new(ListNode)
newList.Val = val
newList.Next = head
return newList
}
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
/**
* 1.判断那个链表更长
*/
size1 := 0
tmp := l1
for tmp != nil {
size1++
tmp = tmp.Next
}
fmt.Printf("size1: %v\n", size1)
size2 := 0
tmp = l2
for tmp != nil {
size2++
tmp = tmp.Next
}
fmt.Printf("size2: %v\n", size2)
longList := l1
shotList := l2
if size1 < size2 {
longList = l2
shotList = l1
}
//遍历长结点
tmpLongList := longList
//进位标志
carryFlag := 0
index := 0
for tmpLongList != nil {
index++
num1 := tmpLongList.Val
num2 := 0
//遍历短节点
index2 := 0
tmpShotList := shotList
for tmpShotList != nil {
index2++
if index2 == index {
num2 = tmpShotList.Val
break
}
tmpShotList = tmpShotList.Next
}
fmt.Printf("num1:%d,num2:%d\n", num1, num2)
sum := num1 + num2 + carryFlag
if carryFlag == 1 {
carryFlag = 0
}
if sum >= 10 {
carryFlag = 1
sum = sum % 10
}
tmpLongList.Val = sum
// fmt.Printf("sum: %v\n", sum)
tmpLongList = tmpLongList.Next
}
if carryFlag == 1 {
tmpList := longList
//找到最好一个节点
for tmpList.Next != nil {
tmpList = tmpList.Next
}
newListNode := new(ListNode)
newListNode.Next = nil
newListNode.Val = 1
tmpList.Next = newListNode
}
fmt.Printf("carryFlag: %v\n", carryFlag)
return longList
}
func main() {
/**
* 构造链表 3 ---> 4->3 ---> 2->4->3 342
*/
list1 := new(ListNode)
list1.Val = 3
list1.Next = nil
list1 = insert(list1, 4)
list1 = insert(list1, 2)
// list := list1
// for list != nil {
// fmt.Printf("list1.Val: %v\n", list.Val)
// list = list.Next
// }
/**
* 构造链表 4 ---> 6->4 ---> 5->6->4 465
*/
list2 := new(ListNode)
list2.Val = 4
list2.Next = nil
list2 = insert(list2, 6)
list2 = insert(list2, 5)
//两数相加求和 342+465=807 7->0->8
listNew := addTwoNumbers(list1, list2)
print("====================\n")
list := listNew
for list != nil {
fmt.Printf("list1.Val: %v\n", list.Val)
list = list.Next
}
}
首先找到最长的链表和最短的链表,一样长就不用管了
在长链表遍历的循环内遍历短链表,对数字逐个相加得到新的长链表