// linked-list, recursion
const { LinkedList, ListNode, compareObjects, LLToArr } = require('../../utils')
// Using LinkedList
function sumLists(ll1, ll2) {
const sumList = new LinkedList()
const recurse = (head1, head2, carryOver = 0) => {
if (!head1 && !head2 && carryOver === 0) {
return sumList
}
let currSum = carryOver
if (head1) {
currSum += head1.val
head1 = head1.next
}
if (head2) {
currSum += head2.val
head2 = head2.next
}
const sumVal = currSum % 10
carryOver = currSum > 9 ? 1 : 0
sumList.appendToTail(sumVal)
return recurse(head1, head2, carryOver)
}
return recurse(ll1, ll2)
}
/*
n = length of first linked list
m = length of second linked list
Time Complexity - O(n + m)
Space complexity - O(n + m)
*/
/* ---------------------------------------------------------------------------- */
// Using ListNode
function sumListsForward(ll1, ll2) {
let sum = { sum: null, carry: 0 }
const len1 = getLength(ll1),
len2 = getLength(ll2)
let list1 = ll1,
list2 = ll2
if (len1 < len2) {
list1 = padList(ll1, len2 - len1)
}
if (len2 < len1) {
list2 = padList(ll2, len1 - len2)
}
const fullSum = partialSum(list1, list2)
if (fullSum.carry === 0) return fullSum.sum
else {
return insertBefore(fullSum.sum, sum.carry)
}
// Helpers
function partialSum(ll1, ll2) {
if (!ll1 && !ll2) return sum
sum = partialSum(ll1.next, ll2.next)
const val = ll1.val + ll2.val + sum.carry,
sumList = insertBefore(sum.sum, val % 10)
sum.sum = sumList
sum.carry = val > 9 ? 1 : 0
return sum
}
function getLength(node) {
let len = 0,
curr = node
while (curr) {
curr = curr.next
len++
}
return len
}
function padList(head, padding) {
let newHead = head
for (let i = 0; i < padding; i++) {
newHead = insertBefore(newHead, 0)
}
return newHead
}
function insertBefore(head, val) {
const node = new ListNode(val)
if (head) {
node.next = head
}
return node
}
}
/*
n = length of first linked list
m = length of second linked list
Time Complexity - O(n + m)
Space complexity - O(n + m)
*/
/* ---------------------------------------------------------------------------- */
// Tests
function testSumLists() {
const lists = []
const arrs = [
[7, 1, 6],
[5, 9, 2],
[9, 1, 3],
[8, 2],
]
for (let i = 0; i < 4; i++) {
ll = new LinkedList()
ll.fromArray(arrs[i])
lists.push(ll)
}
const testCases = [
[lists[0], lists[1], [2, 1, 9]],
[lists[2], lists[3], [7, 4, 3]],
]
console.log('Sum Lists')
for (const test of testCases) {
const res = sumLists(test[0].head, test[1].head).printList()
compareObjects(res, test[2])
}
}
function testSumListsForward() {
const lists = []
const arrs = [
[6, 1, 7],
[2, 9, 5],
[9, 1, 3],
[9, 2],
]
for (let i = 0; i < 4; i++) {
ll = new LinkedList()
ll.fromArray(arrs[i])
lists.push(ll)
}
const testCases = [
[lists[0], lists[1], [9, 1, 2]],
[lists[2], lists[3], [1, 0, 0, 5]],
]
console.log('Sum Lists Forward')
for (const test of testCases) {
const res = sumListsForward(test[0].head, test[1].head)
console.log(LLToArr(res))
compareObjects(LLToArr(res), test[2])
}
}
testSumLists()
testSumListsForward()