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:
>