Task:
Given a linked list, remove the nth node from the end of list and return its head.
For example,
Given linked list: 1->2->3->4->5, and n = 2. After removing the second node from the end, the linked list becomes 1->2->3->5.
Note:
Given n will always be valid.
Try to do this in one pass.
Some Questions:
What's the length of the linked list?
Solution:
If there is no limitation of one pass, the solution is obvious: get the length of the linked list, say m, then iterates the linked list from head to find the (m-n+1)-th element and delete it.
Above-mentioned algorithm runs in O(n) time complexity and O(1) space complexity. But it didn't meet the restriction of one pass.
How to realize it?
We can use two pointers p1,p2.
Step 1: Assign head to p1 and p2;
Step 2: Let p2 moves n steps ahead;
Step 3: p1 and p2 move ahead together uniti p2 is NULL;
Finally we will find p1 locates at the last n-th element miraculously!
Thus we solve this problem perfectly.
Code:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode *p1=head,*p2=head,*pre;//step 1
pre=NULL;
int i;
for(i=0,p2=head;i<n;i++)//step 2
{
p2=p2->next;
}
p1=head;
while(p2)//step 3
{
p2=p2->next;
pre=p1;
p1=p1->next;
}
if(pre!=NULL)
pre->next=p1->next;
else head=head->next;
return head;
}
};