3
\$\begingroup\$

I have some imminent interviews and want to sharpen my game before going into them. I'm running through some practice problems. This LeetCode challenge is to add two numbers represented as linked lists.

If you can critique this solution quite harshly, as though you would in a full-fledged SWE interview, I'd greatly appreciate it. I'm particularly concerned about memory usage and variable names.

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:         
        final_l = None
        curr_l = None
        remainder = 0
        while l1 or l2:
            digit = 0
            if l1:
                digit += l1.val
                l1 = l1.next    

            if l2: 
                digit += l2.val
                l2 = l2.next            

            if remainder != 0:    
                digit += remainder

            remainder = digit // 10
            digit = digit % 10 

            if final_l is None:
                final_l = ListNode(digit)
                curr_l = final_l
            else:
                curr_l.next = ListNode(digit)
                curr_l = curr_l.next            

        if remainder > 0:
            curr_l.next = ListNode(remainder)


        return final_l
\$\endgroup\$
4
\$\begingroup\$

A bit of scaffolding

In order to test/review your code, I had to write a bit of additional code. In case it can be relevant to you or other reviewers, here it is:

# Definition for singly-linked list.
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

    def __eq__(self, other):
        ret = other is not None and self.val == other.val and self.next == other.next
        # print(self, other, ret)
        return ret

    @classmethod
    def from_list(cls, l):
        ret = ln = cls(l.pop(0))
        while l:
            e = l.pop(0)
            ln.next = cls(e)
            ln = ln.next
        return ret

    def to_list(self):
        l = [self.val]
        return l if self.next is None else l + self.next.to_list()

class Solution:
    ...

    @staticmethod
    def ListNodeFromInt(n):
        return ListNode.from_list([int(d) for d in reversed(str(n))])

    @staticmethod
    def testAddTwoNumbersUsingNumbers(n1, n2):
        l1 = Solution.ListNodeFromInt(n1)
        l2 = Solution.ListNodeFromInt(n2)
        expected_add = Solution.ListNodeFromInt(n1 + n2)
        add = Solution().addTwoNumbers(l1, l2)
        print(n1, n2, n1 + n2, expected_add.to_list(), add.to_list())
        assert expected_add == add


    @staticmethod
    def unitTests():
        # Edge cases
        Solution.testAddTwoNumbersUsingNumbers(0, 0)
        Solution.testAddTwoNumbersUsingNumbers(342, 0)
        Solution.testAddTwoNumbersUsingNumbers(0, 342)
        # Same length
        Solution.testAddTwoNumbersUsingNumbers(342, 465)
        # Different length
        Solution.testAddTwoNumbersUsingNumbers(342, 46)
        # Return longer than input
        Solution.testAddTwoNumbersUsingNumbers(999, 999)

Solution.unitTests()

This is pretty poorly organised but it is quick and dirty. Now starts the actual review

Overall review

Your code looks good. The API is a bit awkward but it is a limitation from the programming challenge platform.

A few details can be improved anyway.

Remove non-required checks

Instead of:

        if remainder != 0:    
            digit += remainder

You can write:

        digit += remainder

Use builtins

The builtin divmod is not the most famous but it is convenient for a pretty usual task: compute both the quotient and the remainder.

Instead of:

        remainder = digit // 10
        digit = digit % 10 

You can write:

        remainder, digit = divmod(digit, 10)

Different strategy

Instead of having a function to perform all the steps in one go, you could split the problem: define a function computing the sum of the 2 list as an integer and a function to convert that number into a list. Adding values bigger than 9 may be what we are trying to avoid though...

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.