TABLE OF CONTENTS
Problem Statement
Thought Process
Approach
Solution
Complexity
Conclusion
Hello, Welcome to my Day 1 of Problem Solving and finding solutions to Leetcode's Data Structures and Algorithm questions. Here, I choose a question daily and try to solve it, and finally pen down my process of flow in solving the question.
I hope you find it helpful. Today I will be solving Leetcode's question 19 - Remove Nth Node From End of List.
Problem Statement
- Given the
head
of a linked list, remove then<sup>th</sup>
node from the end of the list and return its head.
Example 1
Input: head = [1,2,3,4,5], n = 2 Output: [1,2,3,5]
Example 2
Input: head = [1], n = 1 Output: []
Example
Input: head = [1,2], n = 1 Output: [1]
Thought Process
One approach I had on solving this question was to traverse the linked list to determine its length, subtract 'n' from its length to find the node to be removed from the start of the LinkedList, then traverse the linked list again to remove the node. However, this approach requires two passes through the linked list and has a time complexity of 0(2n) or 0(n).
Two-Pointer Techniques
A more efficient approach is to use the two-pointer technique. We can maintain two pointers left
and right
and initialize them to point to the head of the linked list. First, we move the right
pointer n
nodes forward in the linked list. If the right
pointer reaches the end of the linked list, the node to be removed is the head node. Otherwise, we move both pointers left
and right
forward until the right
pointer reaches the end of the linked list. At this point, the left
pointer is pointing to the node before the node to be removed, and we can remove the nth
node by updating the next
pointer of the left
node to point to the node after the node to be removed.
This approach only requires one pass through the linked list and has a time complexity of O(n) and a space complexity of O(1), where n is the length of the linked list.
The Approach
Here is my approach in solving the problem using a two-pointer technique
Initialize two pointers
left
andright
to point to the head of the linked list.Move the
right
pointern
nodes forward in the linked list. If theright
pointer reaches the end of the linked list, the node to be removed is the head node. In this case, remove the head node and return thenext
node.Otherwise, move both pointers
left
andright
forward until theright
pointer reaches the end of the linked list. At this point, theleft
pointer is pointing to the node before the node to be removed.Remove the
nth
node by updating thenext
pointer of theleft
node to point to the node after the node to be removed.Return the head of the updated linked list.
The code Snippet
class Solution:
def removeNthFromEnd(self, head:ListNode, n:int) -> ListNode:
dummy = ListNode(0, head)
left = dummy
right = head
while n > 0 and right:
right = right.next
n -= 1
while right:
left = left.next
right = right.next
#delete
left.next = left.next.next
return dummy.next
Explanation of the code
# line 5-7 This line defines a class Solution with a method removeNthFromEnd that takes in two arguments: a head node of a linked list and an integer n representing the node to be removed from the end of the linked list. This method returns the head of the updated linked list after the node is removed.
# Line 7-9 -
# These lines initialize a dummy node with a value of 0 and set its next pointer to the head node. This dummy node is used to handle the case where the head node needs to be removed. Then, two pointers, left and right, are initialized with left pointing to the dummy node and right pointing to the head node.
# Line 11-13 - This loop moves the right pointer n nodes forward while n is greater than 0 and right is not None. This places the right pointer at the (n+1)th node from the end of the linked list.
#line 15-17 - This loop moves both the left and right pointers forward until the right pointer reaches the end of the linked list. This leaves the left pointer at the (n+1)th node from the end of the linked list.
#line 20-21 - This line sets the left pointer's next pointer to the node after the node to be removed. This removes the node from the linked list.
# This line removes the nth node by updating the next pointer of the left node to point to the node after the node to be removed. Finally, the method returns the head of the updated linked list, which is the next node of the dummy node.
Complexity
Time Complexity:
The solution only traverses the linked list once, which takes O(n) time, where n is the length of the linked list.
In addition, we perform constant time operations such as pointer updates and arithmetic operations.
Therefore, the time complexity of the solution is O(n).
Space Complexity:
The solution only uses three pointers:
head
,left
, andright
, and a constant number of integer variables.Therefore, the space complexity of the solution is O(1), which is constant space.
Conclusion
In conclusion, the problem of removing the Nth node from the end of a linked list can be efficiently solved using the two-pointer technique. By using two pointers, we can avoid the need to traverse the linked list twice, which would result in a higher time complexity. Instead, we can traverse the linked list once and determine the node to be removed by maintaining a fixed distance between the two pointers.
The solution also highlights the importance of careful pointer manipulation when working with linked lists. By using a dummy node to simplify edge cases, and by updating the next
pointer of the left
node to remove the nth
node, we can effectively remove the node from the linked list while preserving the overall structure of the list.