Posts Practice Linked List with Python Code
Post
Cancel

Practice Linked List with Python Code

Question: An implementation of a singly double list

Explanation: Here we have 6 different methods on the class of the linked list. Where you can get, addAthead, addAtTail, addAtindex and deleteAtIndex. Each of these methods perform an action related to the singly linkedList behaviour.

class MyLinkedList:

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.list= []


    def get(self, index: int) -> int:
        """
        Get the value of the index-th node in the linked list. If the index is invalid, return -1.
        """
        if index >= len(self.list):
            return -1
        return self.list[index]


    def addAtHead(self, val: int) -> None:
        """
        Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list.
        """
        self.list= [val] + self.list


    def addAtTail(self, val: int) -> None:
        """
        Append a node of value val to the last element of the linked list.
        """
        self.list.append(val)


    def addAtIndex(self, index: int, val: int) -> None:
        """
        Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted.
        """
        if index > len(self.list):
            return

        self.list.insert(index, val)

    def deleteAtIndex(self, index: int) -> None:
        """
        Delete the index-th node in the linked list, if the index is valid.
        """
        if index >= len(self.list):
            return
        del self.list[index]



# Your MyLinkedList object will be instantiated and called as such:
# obj = MyLinkedList()
# param_1 = obj.get(index)
# obj.addAtHead(val)
# obj.addAtTail(val)
# obj.addAtIndex(index,val)
# obj.deleteAtIndex(index)


Question: Given a linked list, determine if it has a cycle in it. To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.

Explanation: we check if a linked list has a cycle in by creating 2 pointers. A fast runner and a slow runner. When they both meet each other, that means the linkedList is cyclic.

class Solution:
    def hasCycle(self, head) -> bool:

        fast, slow = head, head

        while fast and fast.next:
            slow= slow.next
            fast= fast.next.next

            if fast == slow:
                return True

        return False

Question:Linked List Cycle II: Given a linked list, return the node where the cycle begins. If there is no cycle, return null. To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.

Explanation: Similiar to the previous question, we try to find out at which node does the cycle start. For this, we used Floyd’s cycle detection method. Where when the fast and slow runner meets, the fast runner is reset to the head, and when it meets the slow runner again, that is the start of the cycle.

# use Floyd's cycle detection

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        fast, slow = head, head

        while fast and fast.next:
            slow= slow.next
            fast= fast.next.next

            # where they meet, take the fast back to head
            # the distance between head and the start of the cycle
            # equals the distance between where they met and the start of the cycle
            if fast == slow:
                fast= head

                while fast != slow:
                    fast= fast.next
                    slow= slow.next
                return slow

        return None

Question:Intersection of Two Linked Lists: Write a program to find the node at which the intersection of two singly linked lists begins. Notes:

  • If the two linked lists have no intersection at all, return null.
  • The linked lists must retain their original structure after the function returns.
  • You may assume there are no cycles anywhere in the entire linked structure.
  • Your code should preferably run in O(n) time and use only O(1) memory.

Explanation: While both linked linkedList do not equal each other, We iterate through the length of one linkedList, and then jump to the other. If they are linked, both linkedList will eventually cross.

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

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:

        #return None directly if headA or headB are null
        if not headA or not headB:
            return None

        #keep the original structure of headA and headB by saving them
        savedA, savedB = headA, headB

        # while both values are not equal iterate. When none is reached
        # to one of the lists, go to the other list and iterate from there.
        # if there is a connection they will both meet at the same node

        while headA != headB:
            headA= savedB if not headA else headA.next
            headB= savedA if not headB else headB.next

        return headA

Question:Remove Nth Node From End of List: Given a linked list, remove the n-th node from the end of list and return its head.

Explanation: In linkedList, deleting works by skipping the reference connection. Such as

``` second.next = second.next.next

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
We move the first pointer to where we want to delete the node, and then traverse the second node, the same number of steps as the first node when it reaches None/null. This is the node to be deleted and we can skip is using the line shown earlier.

```Python
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        first, second = head, head

        #Take the first.next to the position of the node
        for i in range(n):
            first= first.next

        # if first.next is None, then nothing to delete and return the head as is
        if not first:
            return head.next

        # iterate both till null is reached
        while first.next:
            first= first.next
            second= second.next

        # This connects the second.next to second.next.next, by dropping the node
        second.next = second.next.next

        return head


Question:Reverse a singly linked list.

Input: 1->2->3->4->5->NULL Output: 5->4->3->2->1->NULL

A linked list can be reversed either iteratively or recursively. Could you implement both?

Explanation: The first thing we do is create a temprorily variable to store the pointer of the next value using next= head.next, we later point this next to the head head= next. We then point the the head.next to the previous value head.next= prev so we can reverse the arrows. We then point the prev to the current head.

class Solution:
    def reverseList(self, head: ListNode) -> ListNode:

        prev= None

        # we flip the orientation of the arrow to reverse the list
        while head:
            next= head.next # temp variable to keep track of what is suppose to be next
            head.next= prev # We point the head.next to the prev value
            prev= head # We update the prev value to be the current head
            head= next # We update the head to point next, which was the temp value we created

        reversed = prev
        return reversed



Question: Remove Linked List Elements

Explanation:

class Solution:
    def removeElements(self, head: ListNode, val: int) -> ListNode:

        dummy = ListNode(None)
        dummy.next = head

        prev = dummy
        curr = head

        while curr:

            if curr.val == val:
                prev.next = curr.next

            else:
                prev = curr

            curr = curr.next

        return dummy.next


Question: Odd Even Linked List

Explanation:

class Solution:
    def oddEvenList(self, head: ListNode) -> ListNode:

        even_head= ListNode(None)
        even= even_head

        odd_head= ListNode(None)
        odd= odd_head

        while head:
            odd.next= head
            odd= odd.next
            even.next= head.next
            even= even.next

            head= head.next.next if even else None

        odd.next= even_head.next
        return odd_head.next


Question: Palindrome Linked List

Explanation:

class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        fast= head
        slow= head
        rev= None
        tmp_slow= None

        while fast and fast.next:
            fast= fast.next.next
            tmp_slow= slow.next
            slow.next= rev
            rev= slow
            slow= tmp_slow

        if fast:
            slow= slow.next

        while slow:
            if slow.val != rev.val:
                return False
            slow= slow.next
            rev= rev.next

        return True


Question: Explanation:




Question: Explanation:




This post is licensed under CC BY 4.0 by the author.