Add Two Numbers

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 contain a single digit. Add the two numbers and return it as a linked list.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.

//given ListNode definition
function ListNode(val) {
   this.val = val;
   this.next = null;
}
var addTwoNumbers = function(l1, l2) {
    //add numbers from two linked list and return the sum as a linked list
    let carry=0;
    let head=new ListNode(0);
    let curr=head;
    while (l1 || l2) {
        let l1val=0;
        let l2val=0;
        if (l1) {
            l1val=l1.val;
            l1=l1.next;
        }
        if (l2) {
            l2val=l2.val;
            l2=l2.next;
        }
        let thisDigit=l1val+l2val+carry;
        carry=0;
        if (thisDigit>=10) {
            thisDigit=thisDigit-10;
            carry++;
        }
        curr.next=new ListNode(thisDigit);
        curr=curr.next;
    }
    
    //fill in remaining digit
    if (carry>0) {
        curr.next=new ListNode(carry);
    }
    
    //take out head node
    return head.next;
};

Approaches:
Think back to elementary school math on how you add two numbers together. You put them on top of each other, add from least significant to most significant, and carry the digit if it’s over 9.
The linked list being given in reverse order actually helps us here, since it means we’re traversing from least significant to most significant.

Code Breakdown:
Let’s look at relevant portions of the code and comment on that.

    let carry=0;
    let head=new ListNode(0);
    let curr=head;
    while (l1 || l2) {

First we set up some variables.
head will be the new linked list representing our final answer.
carry is the carry-over digit from adding two numbers together (eg: 7+7=14, so we carry over 4)
curr is just to keep track of where we’re at in the resulting linked list. We’re declaring it here to ensure it stays in scope for rest of our function.
Now we run the loop for as long as l1 and l2 are not null.

        let l1val=0;
        let l2val=0;
        if (l1) {
            l1val=l1.val;
            l1=l1.next;
        }
        if (l2) {
            l2val=l2.val;
            l2=l2.next;
        }

We’re declaring two variables inside the loop, l1val and l2val, initialized to be zero. Note that at every iteration this gets scoped out and re-declared.
If l1 is not null, we haven’t reached the end of the linked list. So we set l1val to be the current value of where we’re at in l1, and then move to next node for l1 linked list. If it is null, then we’ve reached the end of the linked list and keep l1val at zero so it doesn’t affect the calculation.
We do the same for l2.

        let thisDigit=l1val+l2val+carry;
        carry=0;
        if (thisDigit>=10) {
            thisDigit=thisDigit-10;
            carry++;
        }
        curr.next=new ListNode(thisDigit);
        curr=curr.next;
     }

We calculate the current digit to be added to the result array. Recall that l1val and l2val will be zero if it reached the end of its respective linked list. We add the current carried value to it from prior calculations if any, and reset the carry to zero. If the digit is 10+, we carry the 1 and subtract 10 from the digit. Reminds you of elementary school math, right? 🙂
Now we create a new ListNode with the current digit as the value, and assign it to be the next node of our result. We move to the latest node (tail) in preparation for next loop if any.
This ends the loop we’re in which continued for as long as l1 or l2 wasn’t null.

    //fill in remaining digit
    if (carry>0) {
        curr.next=new ListNode(carry);
    }
    //take out head node
    return head.next;

If any carry over digit are still remaining, we add that to the end of the result linked list.
We then return the result linked list, starting from the 2nd node from the head. Why the second node? Because our loop appends the resulting values as the next node, but the initial node is empty so we skip it. We could have designed our loop differently by initializing the first node but this is part of our design.