Skip to content

Commit d4306e9

Browse files
committed
Add two numbers
1 parent 910a34e commit d4306e9

File tree

2 files changed

+214
-0
lines changed

2 files changed

+214
-0
lines changed

2.add_two_numbers/add.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// 2. Add two numbers
2+
// Topics: 'Math', 'Recursion', 'Linked List'
3+
// Level: 'Medium'
4+
5+
// 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 contains a single digit. Add the two numbers and return the sum as a linked list.
6+
7+
// You may assume the two numbers do not contain any leading zero, except the number 0 itself.
8+
9+
// Example 1:
10+
11+
// Input: l1 = [2,4,3], l2 = [5,6,4]
12+
// Output: [7,0,8]
13+
// Explanation: 342 + 465 = 807.
14+
15+
// Example 2:
16+
17+
// Input: l1 = [0], l2 = [0]
18+
// Output: [0]
19+
20+
// Example 3:
21+
22+
// Input: l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
23+
// Output: [8,9,9,9,0,0,0,1]
24+
25+
// Constraints:
26+
27+
// The number of nodes in each linked list is in the range [1, 100].
28+
// 0 <= Node.val <= 9
29+
// It is guaranteed that the list represents a number that does not have leading zeros.
30+
31+
package addtwonumbers
32+
33+
// memory O(n) extra
34+
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
35+
dummy := &ListNode{}
36+
current := dummy
37+
carry := 0
38+
39+
for l1 != nil || l2 != nil || carry > 0 {
40+
sum := carry
41+
if l1 != nil {
42+
sum += l1.Val
43+
l1 = l1.Next
44+
}
45+
if l2 != nil {
46+
sum += l2.Val
47+
l2 = l2.Next
48+
}
49+
carry = sum / 10
50+
current.Next = &ListNode{Val: sum % 10}
51+
current = current.Next
52+
}
53+
54+
return dummy.Next
55+
}
56+
57+
// memory O(1) extra
58+
// func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
59+
// cur1 := l1
60+
// prev := cur1
61+
// cur2 := l2
62+
// var carry int
63+
// for {
64+
// sum := carry
65+
// if cur1 == nil && cur2 == nil {
66+
// if carry != 0 {
67+
// prev.Next = &ListNode{Val: carry}
68+
// }
69+
// break
70+
// }
71+
// if cur1 != nil {
72+
// sum += cur1.Val
73+
// }
74+
// if cur2 != nil {
75+
// sum += cur2.Val
76+
// }
77+
78+
// if cur1 != nil {
79+
// cur1.Val = sum % 10
80+
// } else {
81+
// cur2.Val = sum % 10
82+
// prev.Next = cur2
83+
// prev = prev.Next
84+
// }
85+
86+
// if cur1 != nil {
87+
// prev = cur1
88+
// cur1 = cur1.Next
89+
// }
90+
// if cur2 != nil {
91+
// cur2 = cur2.Next
92+
// }
93+
// carry = sum / 10
94+
// }
95+
96+
// return l1
97+
// }
98+
99+
type ListNode struct {
100+
Val int
101+
Next *ListNode
102+
}

2.add_two_numbers/add_test.go

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package addtwonumbers
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
)
7+
8+
func TestAddTwoNumbers(t *testing.T) {
9+
tests := []struct {
10+
name string
11+
l1 *ListNode
12+
l2 *ListNode
13+
want *ListNode
14+
}{
15+
{
16+
name: "example 1: 342 + 465 = 807",
17+
l1: createList([]int{2, 4, 3}),
18+
l2: createList([]int{5, 6, 4}),
19+
want: createList([]int{7, 0, 8}),
20+
},
21+
{
22+
name: "example 2: 0 + 0 = 0",
23+
l1: createList([]int{0}),
24+
l2: createList([]int{0}),
25+
want: createList([]int{0}),
26+
},
27+
{
28+
name: "example 3: 9999999 + 9999 = 10009998",
29+
l1: createList([]int{9, 9, 9, 9, 9, 9, 9}),
30+
l2: createList([]int{9, 9, 9, 9}),
31+
want: createList([]int{8, 9, 9, 9, 0, 0, 0, 1}),
32+
},
33+
{
34+
name: "different lengths: 123 + 4567 = 4690",
35+
l1: createList([]int{3, 2, 1}),
36+
l2: createList([]int{7, 6, 5, 4}),
37+
want: createList([]int{0, 9, 6, 4}),
38+
},
39+
{
40+
name: "carry propagation: 99 + 1 = 100",
41+
l1: createList([]int{9, 9}),
42+
l2: createList([]int{1}),
43+
want: createList([]int{0, 0, 1}),
44+
},
45+
{
46+
name: "single digit with carry: 5 + 5 = 10",
47+
l1: createList([]int{5}),
48+
l2: createList([]int{5}),
49+
want: createList([]int{0, 1}),
50+
},
51+
{
52+
name: "no carry: 1 + 2 = 3",
53+
l1: createList([]int{1}),
54+
l2: createList([]int{2}),
55+
want: createList([]int{3}),
56+
},
57+
{
58+
name: "l1 longer: 12345 + 67 = 12412",
59+
l1: createList([]int{5, 4, 3, 2, 1}),
60+
l2: createList([]int{7, 6}),
61+
want: createList([]int{2, 1, 4, 2, 1}),
62+
},
63+
{
64+
name: "l2 longer: 12 + 3456 = 3468",
65+
l1: createList([]int{2, 1}),
66+
l2: createList([]int{6, 5, 4, 3}),
67+
want: createList([]int{8, 6, 4, 3}),
68+
},
69+
{
70+
name: "multiple carries: 999 + 999 = 1998",
71+
l1: createList([]int{9, 9, 9}),
72+
l2: createList([]int{9, 9, 9}),
73+
want: createList([]int{8, 9, 9, 1}),
74+
},
75+
}
76+
77+
for _, tt := range tests {
78+
t.Run(tt.name, func(t *testing.T) {
79+
got := addTwoNumbers(tt.l1, tt.l2)
80+
if !equalLists(got, tt.want) {
81+
t.Errorf("addTwoNumbers() = %v, want %v", listToSlice(got), listToSlice(tt.want))
82+
}
83+
})
84+
}
85+
}
86+
87+
func createList(vals []int) *ListNode {
88+
if len(vals) == 0 {
89+
return nil
90+
}
91+
head := &ListNode{Val: vals[0]}
92+
current := head
93+
for i := 1; i < len(vals); i++ {
94+
current.Next = &ListNode{Val: vals[i]}
95+
current = current.Next
96+
}
97+
return head
98+
}
99+
100+
func listToSlice(head *ListNode) []int {
101+
var result []int
102+
current := head
103+
for current != nil {
104+
result = append(result, current.Val)
105+
current = current.Next
106+
}
107+
return result
108+
}
109+
110+
func equalLists(l1, l2 *ListNode) bool {
111+
return reflect.DeepEqual(listToSlice(l1), listToSlice(l2))
112+
}

0 commit comments

Comments
 (0)