using python to complete a LeetCode question #2

Question:

The following is my code which tries to add the two numbers, which are also stored in a linked list in reverse order, and returns the sum as a linked list.

But when I try to run this code in LeetCode, it states this exceeds the time. I assume that it may get stuck in the while loop?

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

class Solution(object):
    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        result = ListNode()
        carry = 0 
    
        while l1 != None or l2 != None or carry:
            if l1 == None:
                v1 = 0
            else:
                v1 = l1.val
                
            if l2 == None:
                v2 = 0
            else:
                v2 = l2.val
        
            total = v1 + v2 + carry 
            carry = total // 10
            total = total % 10
        
            result.next = ListNode(total)
            
            if l1 != None:
                l1.next
                
            if l2 != None:
                l2.next
        
        return result
Asked By: user17118231

||

Answers:

Analysis

This is nothing but a simple elementary addition problem. The only difference is that the numbers to be added are represented by linked list where each digit is represented by the nodes of that linked list.

If we see the example then we will see that the digits are in the reverse order i.e.,

First node => ones place
Second node => tens place
Third node => hundreds place
... and so on.

Thus 2 -> 4 -> 3 will actually make 342 and 5 -> 6 -> 4 will actually make 465.

We will have to return a new linked list whose nodes will represent the digits of the sum of the numbers represented by the given two linked list.

Approach

  1. Traverse two linked lists.
  2. In each iteration, add the numbers in the nodes of the linked lists.
  3. If the lists are unequal, then the smaller one will end before the longer. In this case, we will put only the remaining nodes of the
    longer list in the resultant list.
  4. If the sum of two digits is greater than 9, then we will have to find out the “carry” to be added in the next iteration.

This is nothing more than a simple addition. The only challenge here might be to avoid NullPointerException which is very common in the linked list based problems.

Time Complexity

Since we are iterating both the lists only once, the time complexity would be O(m + n). Here m and n are the numbers of nodes in the two linked lists.

Space Complexity

Since we are using extra space only for our variables, our space complexity would be O(1). One might argue that we are using another list to store our result so the space complexity should also be O(m + n). But this is the list we are not using for our algorithm, we are using it for the result which is asked in the question (I’d love to know your take on this).

Code

def addTwoNumbers(l1: ListNode, l2: ListNode) -> ListNode:
    # Head of the new linked list - this is the head of the resultant list
    head = None
    # Reference of head which is null at this point
    temp = None
    # Carry
    carry = 0
    # Loop for the two lists
    while l1 is not None or l2 is not None:
        # At the start of each iteration, we should add carry from the last iteration
        sum_value = carry
        # Since the lengths of the lists may be unequal, we are checking if the
        # current node is null for one of the lists
        if l1 is not None:
            sum_value += l1.val
            l1 = l1.next
        if l2 is not None:
            sum_value += l2.val
            l2 = l2.next
        # At this point, we will add the total sum_value % 10 to the new node
        # in the resultant list
        node = ListNode(sum_value % 10)
        # Carry to be added in the next iteration
        carry = sum_value // 10
        # If this is the first node or head
        if temp is None:
            temp = head = node
        # for any other node
        else:
            temp.next = node
            temp = temp.next
    # After the last iteration, we will check if there is carry left
    # If it's left then we will create a new node and add it
    if carry > 0:
        temp.next = ListNode(carry)
    return head
Answered By: Sran012

There were few things only which I have changed in the code you wrote.

        result = ListNode(0)
        result_tail = result #### added 
        carry = 0 
    
        while l1 or l2 or carry:
            if l1 == None:
                v1 = 0
            else:
                v1 = l1.val
                
            if l2 == None:
                v2 = 0
            else:
                v2 = l2.val
        
            total = v1 + v2 + carry 
            carry = total // 10
            total = total % 10
        
            result_tail.next = ListNode(total)  ### edited
            result_tail = result_tail.next   ### added
            
            if l1 != None:
                l1 = l1.next ### edited
            else:
                l1 = None   ### added
                
            if l2 != None:
                l2 = l2.next    ### edited
            else:
                l2 = None    ### added
                
        return result.next   ### edited

The major thing I wish you to know is that when you wrote l1.next then you are just giving a command which needs a variable to store the value thus the changes go l1 = l1.next.
Similarly, when you wrote the same statement you need a counter else statement where you need to address the condition when if condition fails. Since that condition was not present, the while loop runs infinitely.

The final part is where I added a result_tail. By giving a try and error, I saw that if we are not adding it then the values of the result get updated instead of getting appended.

Lastly, It is not a dumb question. Just a friendly suggestion, if you are super new, instead of writing the medium-level code start with easy codes of all concepts. It will help you to know more about specific deals in python like the dictionary, default dictionary, list comprehension, list traversing, tuples, sets, enumerators and all. You may have done competitive coding earlier but to be honest, a new innings always starts on 0.

Answered By: Shikhar Gupta