Search code examples
pythonclasslinked-listcallinstantiation

How to call/instantiate linked list


I am trying to call/print the following linked list:

#--the following code is taken from the most upvoted solution at codesignal--
 class ListNode(object):
   def __init__(self, x):
     self.value = x
     self.next = None

def removeKFromList(l, k):
    c = l
    while c:
        if c.next and c.next.value == k:
            c.next = c.next.next
        else:
            c = c.next
    return l.next if l and l.value == k else l

I want to call/instantiate the class with l = [3, 1, 2, 3, 4, 5] and k = 3 and I am expecting it to return => [1, 2, 4, 5] Basically, I am not able to first instantiate the ListNode class and then call the removeKFromList method inside it.. You can find this challenge at: https://app.codesignal.com/interview-practice/task/gX7NXPBrYThXZuanm/description

Description:

Note: Try to solve this task in O(n) time using O(1) additional space, where n is the number of elements in the list, since this is what you'll be asked to do during an interview.

Given a singly linked list of integers l and an integer k, remove all elements from list l that have a value equal to k.

Example

For l = [3, 1, 2, 3, 4, 5] and k = 3, the output should be

removeKFromList(l, k) = [1, 2, 4, 5]

For l = [1, 2, 3, 4, 5, 6, 7] and k = 10, the output should be

removeKFromList(l, k) = [1, 2, 3, 4, 5, 6, 7]

Input/Output

execution time limit: 4 seconds (py3)

input: linkedlist.integer l

A singly linked list of integers.

Guaranteed constraints:

  • 0 ≤ list size ≤ 105,
  • -1000 ≤ element value ≤ 1000.

input: integer k

An integer.

Guaranteed constraints:

  • -1000 ≤ k ≤ 1000.

output: linkedlist.integer

Return l with all the values equal to k removed.


Solution

  • Looking at the comments you made, there are some misunderstandings to resolve here:

    How to create a list

    It seems you expected one of these to create a list:

    a = ListNode({}) 
    

    or

    a = ListNode
    

    Neither is what you need. The ListNode constructor will create one node of a potentially linked list, but you must establish the links "yourself". Passing {} to that constructor makes little sense: that {} is a dictionary and has nothing to do with this data structure. The second form will not even call the constructor, it merely copies the class object to your variable a, which is not what you want.

    Putting it in very verbose terms, the example list is created like this:

    l = ListNode(3)
    l.next = ListNode(1)
    l.next.next = ListNode(2)
    l.next.next.next = ListNode(3)
    l.next.next.next.next = ListNode(4)
    l.next.next.next.next.next = ListNode(5)
    

    This should highlight how a list is created, but of course it does not look very practical. See further down for a better way.

    How to call the function

    You mentioned in comments the following call:

    a.removeKFromList([1,2,3], 3)
    

    But there are two issues with that:

    1. It assumes that removeKFromList is a method of ListNode (since you prefix it with a.), but it should be a plain function, not a method

    2. The first argument is a standard list, but the code challenge tells you it expects a linked list as first argument

    You would need to call your function as follows:

    result = removeKFromList(l, 3)
    

    Utility functions

    To test your code, add the following functions, which will help you instantiate a linked list (from a standard list) and to verify the content of a linked list (through iterating its values):

    def createList(lst):
        head = None
        for val in reversed(lst):
            node = ListNode(val)
            node.next = head
            head = node
        return head
    
    def iterList(head):
        while head:
            yield head.value
            head = head.next
    

    These will ease your tests.

    So now your driver code -- for turning an input to an output -- can be:

    # define the input
    l = createList([3, 1, 2, 3, 4, 5])
    k = 3
    # run your algorithm
    result = removeKFromList(l, 3)
    # verify it
    print(*iterList(result))
    

    This outputs the expected output for the given example.