Add Two Numbers

Leetcode Problem and Solution

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: l1 = [2,4,3], l2 = [5,6,4]
Output: [7,0,8]
Explanation: 342 + 465 = 807

Example 2:

Input: l1 = [0], l2 = [0]
Output: [0]

Example 3:

Input: l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
Output: [8,9,9,9,0,0,0,1]

Constraints:

  • The number of nodes in each linked list is in the range [1, 100].

  • 0 <= Node.val <= 9

  • It is guaranteed that the list represents a number that does not have leading zeros.

Hint

Approach : Elementary Math

Intuition

Keep track of the carry using a variable and simulate digits-by-digits sum starting from the head of list, which contains the least-significant digit.

Illustration of Adding two numbers

Figure 1. Visualization of the addition of two numbers: 342+465=807342 + 465 = 807342+465=807.
Each node contains a single digit and the digits are stored in reverse order.

Algorithm

Just like how you would sum two numbers on a piece of paper, we begin by summing the least-significant digits, which is the head of l1l1l1 and l2l2l2. Since each digit is in the range of 0…90 \ldots 90…9, summing two digits may "overflow". For example 5+7=125 + 7 = 125+7=12. In this case, we set the current digit to 222 and bring over the carry=1carry = 1carry\=1 to the next iteration. carrycarrycarry must be either 000 or 111 because the largest possible sum of two digits (including the carry) is 9+9+1=199 + 9 + 1 = 199+9+1=19.

The pseudocode is as following:

  • Initialize current node to dummy head of the returning list.

  • Initialize carry to 000.

  • Loop through lists l1l1l1 and l2l2l2 until you reach both ends and carry is 000.

    • Set xxx to node l1l1l1's value. If l1l1l1 has reached the end of l1l1l1, set to 000.

    • Set yyy to node l2l2l2's value. If l2l2l2 has reached the end of l2l2l2, set to 000.

    • Set sum=x+y+carrysum = x + y + carrysum\=x+y+carry.

    • Update carry=sum/10carry = sum / 10carry\=sum/10.

    • Create a new node with the digit value of (sum mod 10)(sum \bmod 10)(summod10) and set it to current node's next, then advance current node to next.

    • Advance both l1l1l1 and l2l2l2.

  • Return dummy head's next node.

Note that we use a dummy head to simplify the code. Without a dummy head, you would have to write extra conditional statements to initialize the head's value.

Take extra caution of the following cases:

Test caseExplanation
l1=[0,1]l1=[0,1]l1=[0,1]

l2=[0,1,2]l2=[0,1,2]l2=[0,1,2] | When one list is longer than the other. | | l1=[]l1=[]l1=[]
l2=[0,1]l2=[0,1]l2=[0,1] | When one list is null, which means an empty list. | | l1=[9,9]l1=[9,9]l1=[9,9]
l2=[1]l2=[1]l2=[1] | The sum could have an extra carry of one at the end, which is easy to forget. |

But the solution I had submitted did not use this approach.

Solution

using System.Numerics;

public class Solution {
    public ListNode AddTwoNumbers(ListNode l1, ListNode l2) {
        BigInteger intA = GetWholeNumber(l1);
        BigInteger intB = GetWholeNumber(l2);
        BigInteger intC = intA + intB;
        ListNode l3 = ConvertToListNode(intC);
        return l3;
    }

    //Get the whole reversed number from the list node
    public BigInteger GetWholeNumber(ListNode currentNode)
    {
        if (currentNode == null) {
            return 0;  // Handle empty list case
        }

        string strNumber = "";
        while (currentNode != null) {
            strNumber += currentNode.val.ToString();  // Correct concatenation
            currentNode = currentNode.next;
        }

        string reversedStr = string.Concat(strNumber.Reverse());  // Efficient reversal
        return BigInteger.Parse(reversedStr);
    }

    //Convert the number into listnode
    public ListNode ConvertToListNode(BigInteger number) {
    string numString = number.ToString();  // Convert to string
    string reversedString = string.Concat(numString.Reverse());

    ListNode head = null;
    ListNode currentNode = null;

    foreach (char digitChar in reversedString) {
        int digitValue = int.Parse(digitChar.ToString());
        ListNode newNode = new ListNode(digitValue);

        if (head == null) {
            head = newNode;
            currentNode = head;
        } else {
            currentNode.next = newNode;
            currentNode = newNode;
        }
    }

    return head;  // Return the head of the linked list
    }
}

Explanation

The two lists were converted to numbers and reversed using the function, "GetWholeNumber".

Then the two numbers are added and the new number is reversed and then converted to a List using the function, "ConvertToListNode".

The code is pretty much straight forward. Though it is not the best and elegant solution, the result was pretty much impressive.