As long as we know the previous and the next nodes of the to-be-deleted node, we can update the pointers to delete the node.

Say there are total nodes in the list. Say the
-th node from the end is the
-th node from the head. Then,
and
. From the head, if we jump
times, we would reach the
-th node from the end. We also move the
prev pointer to facilitate delete.
Time: , space:
.
class Solution:
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
def get_list_length(head: ListNode) -> int:
node_count = 0
t = head
while t:
node_count += 1
t = t.next
return node_count
node_count = get_list_length(head)
dummy = ListNode(next=head)
prev, curr = dummy, head
jump_count = node_count - n
while jump_count > 0:
prev = curr
curr = curr.next
jump_count -= 1
prev.next = curr.next
return dummy.next
Finding the length of the list takes one extra scan. We could do the finding and deleting in a single scan. There are nodes from the to-be-deleted node to the last list node.

So, we start with a current pointer at the head and a forward pointer at the -th node from the head. We then move both pointers together. When the
forward pointer reaches the last list node, the current pointer is at the to-be-delete node. We also track a previous pointer to facilitate delete.
Time: , space:
.
class Solution:
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
dummy = ListNode(next=head)
previous, current = dummy, head
forward, jump = head, n-1
while jump > 0:
forward = forward.next
jump -= 1
while forward.next:
previous = current
current = current.next
forward = forward.next
previous.next = current.next
return dummy.next
The dummy node simplifies the logic but isn’t essential.
class Solution:
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
previous, current = head, head
forward, jump = head, n-1
while jump > 0:
forward = forward.next
jump -= 1
while forward.next:
previous = current
current = current.next
forward = forward.next
if current == head:
return head.next
previous.next = current.next
return head
Leave a comment