Wow that is a lot of code to add two numbers.
Potential bug
The function ListNode has one argument yet in the function addTwoNumbers
you call it with two arguments. However it does not manifest as a bug as you add the link in the lines following the node creation.
This also results in you creating twice as many nodes as needed.
E.G the second node is dropped and never used.
sum = new ListNode(k, new ListNode(k));
Sanitize
The question states that the inputs are digits so there is no need to sanitize the lists. The only time you vet (arr sanitize) input is when that input comes from the insane, only networks and humans can be insane hence you only sanitize data from them. (Why I hate libraries and frameworks.. Their interfaces face humans (via code) so they are full of vetting code that negatively effect their performance)
i
, j
and sometime k
Generally the named variables i
, j
, k
are used as indexes. This is so ubiquitous in C syntax like languages that using them for other purposes is a definite no no.
Use numbers
You should never bring a string to a numbers party.
The variable you call rollover
is called carry
. The carry can be extracted from the sum as carry = sum / 10 | 0
which is a lot faster than converting to a string.
The core of the adder requires 3 numbers a
, b
, and carry
that will give a val
and carry
and use one intermediate to avoid repeating an operation.
sum = a + b + carry,
val = sum % 10;
carry = (sum - val) / 10;
// or
sum = a + b + carry,
val = sum % 10;
carry = sum / 10 | 0;
Testing
I did not fully test your code as it did not fit well with my linked list lib and my brain not work good this morn I'm a little lazy today. If there are other problems I do not see them in the code.
Rewrite
It is assumed that the linked list functions are not part of the problem to solve. The answer contains some list helpers that can be implemented in a variety of ways.
- Node creates a linked list node the new token.
- Helper function for testing
toList
converts an array to a list returning the head node as the most significant digit. (Note | 0
to force type Number
Changes
- No sanity check
- Uses numbers rather than string to find carry
- Uses a
do while
to avoid the extra code needed to handle the final carry (some argue do whiles
are too complex for humans to use and should be avoided, all I can say to the down voters, "Du..Really???")
Edge case
The example show an edge case of zero add zero as long lists of zero
The second version check if the result is zero and returns a single node containing 0
which to me seams to more correct answer.
BUT what about 001 + 1
the result is 002
I have not bothered with this edge case (or "leave it for you to solve if interested")
(hint: hold last node with value)
function Node(val, next){ return {val, next,
toString() {return "" + (this.next ? this.next : "") + this.val}
}};
const toList = (vals, p) => (vals.forEach(v => p = Node(v | 0, p)), p);
const reverseList = (l, p) => {do{p = Node(l.val ,p) }while(l = l.next); return p};
const A = toList([..."33140613"]), B = toList([..."9283629"]);
const A1 = toList([..."00000"]), B1 = toList([..."00000"]);
const A2 = toList([..."00100"]), B2 = toList([..."900"]);
console.log(A + " + " + B + " = " + add(A, B));
console.log("Wrong: " + A1 + " + " + B1 + " = " + add(A1, B1));
console.log("Wrong ?: " + A2 + " + " + B2 + " = " + add(A2, B2));
function add(nA, nB) {
var carry = 0, a, b, result;
do {
nA ? (a = nA.val, nA = nA.next) : a = 0;
nB ? (b = nB.val, nB = nB.next) : b = 0;
const sum = a + b + carry, val = sum % 10;
carry = (sum - val) / 10;
result = Node(val, result);
} while(nA || nB || carry !== 0);
return reverseList(result);
}
Edge case
Return single node for zero.
function Node(val, next){ return {val, next,
toString() {return "" + (this.next ? this.next : "") + this.val}
}};
const toList = (vals, p) => (vals.forEach(v => p = Node(v | 0, p)), p);
const reverseList = (l, p) => {do{p = Node(l.val ,p) }while(l = l.next); return p};
const A = toList([..."33140613"]), B = toList([..."9283629"]);
const A1 = toList([..."00000"]), B1 = toList([..."00000"]);
const A2 = toList([..."00100"]), B2 = toList([..."900"]);
console.log(A + " + " + B + " = " + add(A, B));
console.log(A1 + " + " + B1 + " = " + add(A1, B1));
console.log("Wrong: " + A2 + " + " + B2 + " = " + add(A2, B2));
function add(nA, nB) {
var carry = 0, a, b, result, hasVal = 0;
do {
nA ? (a = nA.val, nA = nA.next) : a = 0;
nB ? (b = nB.val, nB = nB.next) : b = 0;
const sum = a + b + carry, val = sum % 10;
carry = (sum - val) / 10;
result = Node(val, result);
hasVal += sum;
} while(nA || nB || carry !== 0);
return hasVal ? reverseList(result) : Node(0);
}
This answer contains subjective opinions that do not reflect the view of the CR community B.M.