subject
Given a linked list, delete the nth last node of the list and return the head node of the list.
Example:
Given a list: 1 - > 2 - > 3 - > 4 - > 5, and n = 2
When the penultimate node is deleted, the list changes to 1 - > 2 - > 3 - > 5
Explain:
The given n guarantee is valid.
Advance:
Can you try a scan implementation?
Algorithm 1
public class P19_RemoveNode { public ListNode removeNthFromEnd(ListNode head, int n) { if(head == null || head.next == null){ return null; } int length = 1; ListNode p = head.next; while(p!=null){ length++; p = p.next; } int index = length - n + 1; if(index == 1){ return head.next; } ListNode blankHead = new ListNode(0); blankHead.next = head; p = head; int i = 1; while(i<index-1){ i++; p = p.next; } p.next = p.next.next; return blankHead.next; } }
Idea: the simplest two traversal algorithm is used here. The first traversal determines the length and the second traversal deletes a location node, but the algorithm takes less time than expected.
Algorithm 2 (from leetcode)
public class P19_RemoveNode2 { public ListNode removeNthFromEnd(ListNode head, int n) { ListNode dummy = new ListNode(0); dummy.next = head; ListNode first = dummy; ListNode second = dummy; // Advances first pointer so that the gap between first and second is n nodes apart for (int i = 1; i <= n + 1; i++) { first = first.next; } // Move first to the end, maintaining the gap while (first != null) { first = first.next; second = second.next; } second.next = second.next.next; return dummy.next; } }
Train of thought:
The above algorithm can be optimized to use only one traverse. We can use two pointers instead of one. The first pointer moves n+1 steps forward from the beginning of the list, and the second pointer starts from the beginning of the list. Now, the two pointers are separated by N nodes. We keep this constant interval by moving two pointers forward at the same time until the first pointer reaches the last node. The second pointer will point to the nth node from the last node. We re link the next pointer of the node referenced by the second pointer to the next node of the node.