Coding Exercises for Singly Linked Lists in Python

Coding Exercises for Singly Linked Lists in Python

Primary Coding Drills

  1. Create Simple Singly Linked List

     class Node:
         def __init__(self, value):
             self.value = value
             self.next = None
    
     class LinkedList:
         def __init__(self, value):
             new_node = Node(value)
             self.head = new_node
             self.tail = self.head
             self.length = 1
    

    self.length = 1 : For now, the list has only one node.

    self.head = self.tail : Having only one node in the linked list, the node acts as both the head and the tail.

  2. Insertion at the Beginning of a Singly Linked List

     # part of the question 
     class Node: #from this
         def __init__(self, value):
             self.value = value
             self.next = None
    
     class LinkedList:
         def __init__(self):
             self.head = None
             self.length = 0
    
         # Implement Here
         def prepend(self, value): #to this
             # write your answer here
             new_node = Node(value)
             if self.head == None: 
                 self.head = self.tail = new_node
             else: 
                 new_node.next = self.head 
                 self.head = new_node 
             self.length += 1
    

    Create a new node. check if the linked list is empty or not, write two conditions for this. Other operations are same as the append method.

  3. Insertion at the End of a Singly Linked List

     class Node:
         def __init__(self, value):
             self.value = value
             self.next = None
    
     class LinkedList:
         def __init__(self):
             self.head = None
             self.tail = None
             self.length = 0
    
         def append(self, value):
             # TODO
             new_node = Node(value)
             if self.head == None: 
                 self.head = self.tail = new_node
             else: 
                 self.tail.next = new_node 
                 self.tail = new_node 
             self.length += 1
    
  4. Deletion from a Singly Linked List

     #given code 
     class Node:
         def __init__(self, value):
             self.value = value
             self.next = None
    
     class LinkedList:
    
         def __init__(self):
             self.head = None
             self.tail = None
             self.length = 0
    
         def __str__(self):
             temp_node = self.head
             result = ''
             while temp_node is not None:
                 result += str(temp_node.value)
                 if temp_node.next is not None:
                     result += ' -> '
                 temp_node = temp_node.next
             return result
    
         def append(self, value):
             new_node = Node(value)
             if self.head is None:
                 self.head = new_node
                 self.tail = new_node
             else:
                 self.tail.next = new_node
                 self.tail = new_node
             self.length += 1
    
     #your answer here 
         def remove(self, index):
         if index < 0 or index >= self.length:
             return None
    
         # if node to be removed is the head node
         elif index == 0:
             popped_node = self.head
             if self.length == 1:
                 self.head = None
                 self.tail = None
             else:
                 self.head = self.head.next
             popped_node.next = None
             self.length -= 1
             return popped_node
    
         else:
             temp = self.head
             for _ in range(index - 1):
                 temp = temp.next
    
             popped_node = temp.next
    
             # if node to be removed is the tail node
             if popped_node.next is None:
                 self.tail = temp
    
             temp.next = temp.next.next
             popped_node.next = None
             self.length -= 1
             return popped_node
    
  5. Reversing a Singly Linked List

    ```python class Node: def init(self, value): self.value = value self.next = None

    class LinkedList: def init(self): self.head = None self.tail = None self.length = 0

    def str(self): temp_node = self.head result = '' while temp_node is not None: result += str(temp_node.value) if temp_node.next is not None: result += ' -> ' temp_node = temp_node.next return result

    def append(self, value): new_node = Node(value) if self.head is None: self.head = new_node self.tail = new_node else: self.tail.next = new_node self.tail = new_node self.length += 1

TODO

def reverse(self): prev_node = None current_node = self.head while current_node is not None: next_node = current_node.next current_node.next = prev_node prev_node = current_node current_node = next_node self.head, self.tail = self.tail, self.head


6. Middle of a Singly Linked List

    ```python
    class Node:
        def __init__(self, value):
            self.value = value
            self.next = None

    class LinkedList:
        def __init__(self):
            self.head = None
            self.tail = None
            self.length = 0

        def append(self, value):
            new_node = Node(value)
            if self.head is None:
                self.head = new_node
                self.tail = new_node
            else:
                self.tail.next = new_node
                self.tail = new_node
            self.length += 1
    #todo

        def find_middle(self):
            slow = self.head
            fast = self.head
            while fast is not None and fast.next is not None:
                slow = slow.next
                fast = fast.next.next
            return slow

This method, known as the "fast and slow pointer" technique or "tortoise and hare" algorithm, lets you go through the list just once, instead of counting the elements first and then finding the middle one.

  1. Remove Duplicates from a Singly Linked List

    
     class Node:
         def __init__(self, value):
             self.value = value
             self.next = None
    
     class LinkedList:
         def __init__(self):
             self.head = None
             self.tail = None
             self.length = 0
    
         def __str__(self):
             temp_node = self.head
             result = ''
             while temp_node is not None:
                 result += str(temp_node.value)
                 if temp_node.next is not None:
                     result += ' -> '
                 temp_node = temp_node.next
             return result
    
         def append(self, value):
             new_node = Node(value)
             if self.head is None:
                 self.head = new_node
                 self.tail = new_node
             else:
                 self.tail.next = new_node
                 self.tail = new_node
             self.length += 1
     #todo
         def remove_duplicates(self):
             if self.head is None:
                 return
             node_values = set()  # set to store unique node values
             current_node = self.head
             node_values.add(current_node.value)
             while current_node.next:
                 if current_node.next.value in node_values:  # duplicate found
                     current_node.next = current_node.next.next
                     self.length -= 1
                 else:
                     node_values.add(current_node.next.value)
                     current_node = current_node.next
             self.tail = current_node
    

Let me know if the ques were easy to understand or should I elaborate them more with hints. Also, let me know if you are having trouble to understand any specific line.

That's all for today. Next. I will provide some LEETCODE ques with answers.

Stay Hydrated!