
Description
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.
Setup
In LeetCode, the linked list is provided for you. We’ll have to add that ourselves. To make the test cases more readable, we will also add a ToString to print it out, and a factory to easily create it from an array of integers.
class ListNode;
begin
constructor Init(Value : Integer, Next : ListNode := Nil);
begin
this.Value := Value;
this.Next := Next;
end
function ToString() : String;
begin
var ToString := Str('[') + Value;
var Current := Next;
while Current <> Nil do
begin
ToString := ToString + ', ' + Current.Value;
Current := Current.Next;
end
ToString := ToString + ']';
Exit ToString;
end
end
function LinkedList(Values : Array of Integer) : ListNode;
var
Head, Current : ListNode;
begin
if Values.Length = 0 then raise 'Must contain at least one node!';
Head := ListNode(0);
Current := Head;
for var I := Iterator(Values); I.HasNext() do
begin
Current.Next := ListNode(I.Next());
Current := Current.Next;
end
Exit Head.Next;
end
Tests
With that taken care of, we can add the 3 example scenarios as test cases:
test 'Case #1';
begin
var Sum := AddTwoNumbers([2, 4, 3], [5, 6, 4]);
AssertEqual('[7, 0, 8]', Sum.ToString());
end
test 'Case #2';
begin
var Sum := AddTwoNumbers([0], [0]);
AssertEqual('[0]', Sum.ToString());
end
test 'Case #3';
begin
var Sum := AddTwoNumbers([9, 9, 9, 9, 9, 9, 9], [9, 9, 9, 9]);
AssertEqual('[8, 9, 9, 9, 0, 0, 0, 1]', Sum.ToString());
end
Solution
To get a O(n) solution, you just loop through the two linked lists at the same time, and add the two together. If the first or second node is Nil you set that value to 0.
Probably the hardest part of this problem is carrying to 10’s place. You can use division to get the value, and the mod operator to get the carry. The tricky part comes in modifying the while loop to make sure you continue till carry value is gone, even if it goes beyond both linked lists.
Note: it makes the solution easier by creating a dummy head, and just returning the Next property.
function AddTwoNumbers(List1, List2: ListNode) : ListNode;
var
Head, Current : ListNode;
First, Second : Integer;
Sum, Carry : Integer := 0;
begin
Head := ListNode(0, Nil);
Current := Head;
while List1 <> Nil Or List2 <> Nil Or Carry <> 0 do
begin
First := List1 = Nil ? 0 : List1.Value;
Second := List2 = Nil ? 0 : List2.Value;
Sum := First + Second + Carry;
Carry := Sum / 10;
Current.Next := ListNode(Sum % 10);
Current := Current.Next;
List1 := List1?.Next;
List2 := List2?.Next;
end
Exit Head.Next;
end
**********
Bonus
Using operator overloading the code becomes more readable:
operator + (Other : ListNode) : ListNode; begin Exit AddTwoNumbers (this, Other); end
Now the code looks like LinkedList([1, 2, 3]) + LinkedList([4, 5, 6]).
Bonus #2
In an interview the other day I had the good old “reverse a linked list” coding question, in Java of course, but here is the equivalent in Algol-24 😀
/// Add to ListNode class.
///
function Reverse() : ListNode;
var
Current, Previous, Next : LinkedNode := Nil;
begin
Current := this;
while Current <> Nil do
begin
Next := Current.Next;
Current.Next := Previous;
Previous := Current;
Current := Next;
end
Exit Previous;
end
test 'Reverse a linked list';
begin
var TheList := LinkedList([2, 4, 3]);
var Sum := TheList.Reverse();
AssertEqual('[3, 4, 2]', Sum.ToString());
end

Leave a Reply