这是链表算法的第二篇,这是两数相加的升级版,力扣链接。
给你两个 非空链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
示例1:
输入:l1 = [7,2,4,3], l2 = [5,6,4] 输出:[7,8,0,7]
示例2:
输入:l1 = [2,4,3], l2 = [5,6,4] 输出:[8,0,7]
这回就不一样了,不再是头头相加,而是尾尾相加。这种场景符合标准的栈的逻辑,后入先出。Go没有原生的栈,我们组装数组后左右指针也可以实现这个功能。
Go
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
l1List, l2List := getList(l1), getList(l2)
l, r, in := len(l1List)-1, len(l2List)-1, 0
result := &ListNode{}
cur := result
for l >= 0 || r >= 0 {
left := 0
if l >= 0 {
left = l1List[l]
l--
}
right := 0
if r >= 0 {
right = l2List[r]
r--
}
sum := left + right + in
in = sum / 10
cur = &ListNode{
Val: sum % 10,
}
if result.Next != nil {
cur.Next = result.Next
}
result.Next = cur
}
if in != 0 {
cur = &ListNode{
Val: in,
}
if result.Next != nil {
cur.Next = result.Next
}
result.Next = cur
}
return result.Next
}
func getList(n *ListNode) []int {
result := make([]int, 0)
for n != nil {
result = append(result, n.Val)
n = n.Next
}
return result
}
当然可以做一些性能优化:
Go
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
l1List, l2List := make([]int, 0), make([]int, 0)
for l1 != nil || l2 != nil {
if l1 != nil {
l1List = append(l1List, l1.Val)
}
if l2 != nil {
l2List = append(l2List, l2.Val)
}
if l1 != nil {
l1 = l1.Next
}
if l2 != nil {
l2 = l2.Next
}
}
in := 0
result := &ListNode{}
for len(l1List) > 0 || len(l2List) > 0 {
left := 0
if len(l1List) > 0 {
left = l1List[len(l1List)-1]
l1List = l1List[:len(l1List)-1]
}
right := 0
if len(l2List) > 0 {
right = l2List[len(l2List)-1]
l2List = l2List[:len(l2List)-1]
}
sum := left + right + in
in = sum / 10
result.Next = &ListNode{
Val: sum % 10,
Next: result.Next,
}
}
if in != 0 {
result.Next = &ListNode{
Val: in,
Next: result.Next,
}
}
return result.Next
}