19 Remove Nth Node From End of List
Published:
Problem
Solution
Intuition
This problem requires us to return a list with the n-th node from the end removed. We are not given the size of the list so we do not know which node we are to remove on the first pass. We are given the added challenge of solving this problem in one pass which is what we will do.
The intuition behind what we are trying to accomplish is that if three nodes, prev_node
, cur_node
, and next_node
, and we want to remove node cur_node
, we are simply making prev_node.next = next_node
. We only need to therefore keep track of a three node window while stepping through our list. We just need to slide this window over to the correct node and then perform our operation to remove our cur_node
node. Our next problem to sovle is we need to make sure that cur_node
is chosen as the n-th node from the end of the list. This is done by taking a pointer which will be n
nodes ahead of our cur_node
. When our pointer reaches the end of the list, we know that we our cur_node
is the n-th node from the end of the list and we must remove it. We will first move our pointer n
nodes ahead of our window, and then step the pointer and the window ahead by a node until we reach the end of our list. Then we remove cur_node
and return the head of our list.
Approach
- Initialize a
dummy
node which will keep track of the head of our list and also gives us an empty node to start ourprev_node
at. - Initialize
prev_node
,cur_node
, andnext_node
to be centered at ourhead
. These nodes will form our window. - Initialize
pointer
to start athead
. Pointer will be moved to ben
nodes ahead of the center of our window to help us find the end of the list. - Move
pointer
n - 1
nodes ahead. We moven - 1
as the 1st node from the end (n = 1
) is actually the last node. - While we have not reached the end of the list, move our pointer and window ahead by a node.
- After we have placed our window in the correct position, drop
cur_node
, by makingprev_node.next = next_node
. - Return the head of the list.
Complexity
- Time complexity: $O(n)$. We iterate through each node once and perform constant time operations on each iteration.
- Space complexity: $O(1)$. We utilize constant space for our pointer and window.
Code
# Definition for singly-linked list.
# 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
prev_node = dummy
cur_node = head
next_node = head.next
pointer = head
for _ in range(n - 1):
pointer = pointer.next
while pointer.next:
pointer = pointer.next
prev_node, cur_node, next_node = cur_node, next_node, next_node.next
prev_node.next = next_node
return dummy.next