curr will always be the node behind, in case the next node is a duplicate that needs to be removed. Even the head can be removed. Hence having a dummy node solves this problem.
class Solution(object): def deleteDuplicates(self, head): """ :type head: ListNode :rtype: ListNode """ # Time: O(n) # Space: O(1) dummy = ListNode(None) dummy.next = head curr = dummy while curr: has_dup = False # Remove duplicates and leave the last of the duplicates. while curr.next and curr.next.next and curr.next.val == curr.next.next.val: curr.next = curr.next.next has_dup = True if has_dup: # Remove the last duplicate curr.next = curr.next.next else: curr = curr.next return dummy.next