Start learning free

LESSON 275 OF 338 · LINKED LISTS

Add Two Numbers in Go: Digit-by-Digit Addition on Linked Lists

Practice O(n) Read the full explanation

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.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

Example 1:

Input: list1 = [2, 4, 3], list2 = [5, 6, 4]
Output: [7, 0, 8]
Explanation: 342 + 465 = 807


Example 2:

Input: list1 = [9,9,9,9,9,9,9], list2 = [9,9,9,9]
Output: [8,9,9,9,0,0,0,1]
Explanation: 9999999 + 9999 = 10009998


STEP 1 OF 12
    Ctrl + Enter to check

    GO · LINKED LISTS

    Add Two Numbers in Go, explained

    Problem overview

    The function addTwoNumbers receives list1 and list2, two non-empty linked lists of *ListNode. Each list is a non-negative integer with one digit per node, stored in reverse order: the first node holds the ones digit, the next the tens digit, and so on. The function returns their sum in the same format, as a new list.

    For [2, 4, 3] and [5, 6, 4] the numbers are 342 and 465. Their sum, 807, is returned as [7, 0, 8]. For [9, 9, 9, 9, 9, 9, 9] and [9, 9, 9, 9] the numbers are 9999999 and 9999, the sum is 10009998, and the result is [8, 9, 9, 9, 0, 0, 0, 1]. This one is longer than either input, because the last carry creates a new digit.

    Approach: do what you do on paper

    Reverse order is convenient here. Column addition on paper starts at the ones digit, and the lists start there too. So the algorithm walks both lists at once from the front. For each column it adds the two digits (a missing digit counts as 0) plus the carry from the previous column. The digit to store is sum % 10 and the new carry is sum / 10.

    The largest possible column sum is 9 + 9 + 1 = 19, so the carry is always 0 or 1.

    The loop must continue while either list has digits left or a carry is pending. The carry condition matters at the very end: adding [5] and [5] leaves both lists empty after one column, but the sum 10 still has a carry of 1, which needs a second node. The result is [0, 1].

    The result list is built by appending at its tail. To avoid a special case for the first node, the code starts with a dummy node and returns dummy.Next at the end.

    Step by step

    1. Create two cursors, node1, node2 := list1, list2. One := declares both. The cursors move, while the parameters stay put.
    2. Create the dummy: dummy := &ListNode{}. The & before a struct literal gives a pointer to a new node, with fields left out set to zero.
    3. Point tail at the dummy. tail is the last node of the result so far. At first it is the dummy, so the first appended digit becomes dummy.Next.
    4. Start carry at 0.
    5. Loop with a condition-only for (Go's while): node1 != nil || node2 != nil || carry > 0. Go conditions must be booleans, so each test is spelled out.
    6. Start the column sum with the carry: sum := carry. Declaring it inside the loop gives each column a fresh variable.
    7. Add list 1's digit if it exists, then advance node1. An exhausted list contributes nothing, which is the same as a 0 digit.
    8. Do the same for list 2. The two checks are independent, so lists of different lengths work.
    9. Update the carry: carry = sum / 10. Integer division in Go drops the remainder, so this is 1 for sums of 10 to 19 and 0 below 10.
    10. Append the digit: tail.Next = &ListNode{Val: sum % 10}. The remainder after dividing by 10 is the last digit of the sum.
    11. Advance tail onto the new node. Without this, each digit would overwrite the previous one.
    12. Return dummy.Next, the first real digit.

    The solution in Go

    func addTwoNumbers(list1, list2 *ListNode) *ListNode {
    	node1, node2 := list1, list2
    	dummy := &ListNode{}
    	tail := dummy
    	carry := 0
    	for node1 != nil || node2 != nil || carry > 0 {
    		sum := carry
    		if node1 != nil {
    			sum += node1.Val
    			node1 = node1.Next
    		}
    		if node2 != nil {
    			sum += node2.Val
    			node2 = node2.Next
    		}
    		carry = sum / 10
    		tail.Next = &ListNode{Val: sum % 10}
    		tail = tail.Next
    	}
    	return dummy.Next
    }
    

    Go details worth knowing:

    • Tuple declarations. node1, node2 := list1, list2 evaluates the right side first and then assigns in order. It's the same as two separate declarations.
    • Integer division and remainder. With int operands, / truncates toward zero and % takes the sign of the dividend. All values here are non-negative, so sum / 10 and sum % 10 are the carry and the digit.
    • No truthiness. A pointer or an integer can't stand alone as a condition, so the code writes node1 != nil and carry > 0.
    • Composite literals. &ListNode{Val: sum % 10} names the field it sets. Next is left as nil, which is right for a new tail node.
    • No big integers needed. The code never converts the lists into a number. The lists can be far longer than what an int holds, because only one column is ever in a variable.

    Complexity

    Time: O(max(m, n)), where m and n are the lengths. Each iteration consumes one digit from at least one list, except possibly the last, which only writes the final carry. The work per iteration is constant.

    Space: O(max(m, n)) for the result list, which has one node per column, plus one for a final carry. Apart from the output, the extra memory is a few variables.

    Edge cases and common mistakes

    • Lists of different lengths. [9, 9, 9, 9, 9, 9, 9] plus [9, 9, 9, 9] keeps going after the second list is exhausted. The carry moves through the remaining 9s, turning them into 0s, until it becomes a new 1 at the end.
    • Final carry. [5] plus [5] gives [0, 1]. A loop condition of only node1 != nil || node2 != nil would return [0], which means 0.
    • Zero. [0] plus [0] gives [0]: one column, sum 0, no carry.
    • Dereferencing an exhausted list. Reading node2.Val without the node2 != nil check panics once the shorter list ends.
    • Forgetting to advance tail. The result would keep only the last digit, replacing the earlier ones.
    • Returning dummy. That adds a leading 0 node to every answer.

    Testing

    • [2, 4, 3] and [5, 6, 4] gives [7, 0, 8].
    • [9, 9, 9, 9, 9, 9, 9] and [9, 9, 9, 9] gives [8, 9, 9, 9, 0, 0, 0, 1].
    • [5] and [5] gives [0, 1].
    • [0] and [0] gives [0].
    Keep going with GoAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free