24. Swap Nodes in Pairs
Need 3 pointers to do such an operation: to change 2 and 3 we need 1 because we neend to make 1.next = 3 (pre=2). Create a dumy head can be really useful. The while loop should stop when cur.next or cur.next.next = None. i.e. if only one node left we should not bother.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
dummy = ListNode(next = head)
cur = dummy
while cur.next and cur.next.next:
cur_next = cur.next
cur_2next = cur_next.next
cur_next.next = cur_2next.next
cur_2next.next = cur_next
cur.next = cur_2next
cur = cur.next.next
return dummy.next
19. Remove Nth Node From End of List
The key is to right a O(n) solution to only iterate through the linked list once. Todo so, implement the slow and faster pointers and let fast pointer lead for n space when fast reaches the end slow should be at n+1 th from the end, + 1 because we have dummy node.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
dummy = ListNode()
dummy.next = head
fast = dummy
slow = dummy
while fast.next:
if n == 0:
slow = slow.next
else:
n = n-1
fast = fast.next
slow.next = slow.next.next
return dummy.next
160. Intersection of Two Linked Lists
How: find the length of two linked list. start from the common tail and iterate through the rest. If two nodes are equal. then all the following nodes must be equal (because they are the same object). Therefore, return the node.
Common mistake: To avoid not iterate through the last element: , if using dummy node, then node.next != None. If not using dummy node, then node != None.
class ListNode:
def __init__(self, next = None):
self.val = None
self.next = next
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> Optional[ListNode]:
len_a = 0
len_b = 0
count_a = headA
while count_a != None:
len_a += 1
count_a = count_a.next
count_b = headB
while count_b != None:
len_b += 1
count_b = count_b.next
if len_a > len_b:
l_list = ListNode(next = headA)
s_list = ListNode(next = headB)
diff = len_a - len_b
else:
l_list = ListNode(next = headB)
s_list = ListNode(next = headA)
diff = len_b - len_a
for i in range(diff):
l_list = l_list.next
while l_list.next:
if l_list.next == s_list.next:
return l_list.next
l_list = l_list.next
s_list = s_list.next
return None
142. Linked List Cycle II
to solve this question. use a fast and slow pointer. if they meet, then it's a loop. to find where the lopp started, find where the fast and slow encountered, it should have the same distance + n*loop to the loop start point as start does. This is because, x + y = (x + 2y +z)/2, where gives x = z. for a single loop. Need to pay attention that fast and slow should update immediatly when enter the while loop because otherwise they all equal to head.
class Solution:
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
fast,slow = head,head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
if fast == slow:
meet = slow
start = head
while meet != start:
meet = meet.next
start = start.next
return start
return None