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.
做法1:把整个链表reverse一遍,然后正常地找到应该删除的那个位置,删除后,再reverse一遍即可。需要特殊处理的是当n=1时的情况。另外,在做第二遍reverse之前,应当保存当时链表的最后一个结点,以方便返回。
ListNode* removeNthFromEnd(ListNode* head, int n) { ListNode* tail=head; while(tail->next){ tail=tail->next; } reverse(head); head->next=NULL; if(n==1){ tail=tail->next; } ListNode* temp=tail; while(n>=2){ if(n==2){tail->next=tail->next->next;break;} else tail=tail->next; n--; } ListNode* tmp=temp; while(temp&&temp->next){ temp=temp->next; } reverse(tmp); if(tmp&&tmp->next)tmp->next=NULL; return temp; } ListNode* reverse(ListNode* head){ ListNode* temp; if(head&&head->next){ temp=reverse(head->next); temp->next=head; } return head;
}
做法2,灵感来源于做法1,不必真正地reverse,但仍然按照reverse的方向,在刚好回溯到需要删除的结点时正常完成删除即可。
ListNode* removeNthFromEnd(ListNode* head, int n) {
int k=reverse(head,n);
if(k==1||k==0)head=head->next;
return head;
}
int reverse(ListNode* head,int n){
int tmp;
if(head&&!head->next)tmp=n-1;
if(head&&head->next){
tmp=reverse(head->next,n);
if(tmp==0)head->next=head->next->next;
tmp--;
}
return tmp;
}
做法3,最直接的做法,计数链表的长度,然后从头开始,读到指定位置的时候删除即可。
ListNode* removeNthFromEnd(ListNode* head, int n) {
int count=0;
ListNode* temp=head;
ListNode* tmp=head;
while(head){
count++;
head=head->next;
}
int pos=count-n;
if(pos==0)tmp=tmp->next;
while(pos){
if(pos==1)temp->next=temp->next->next;
else temp=temp->next;
pos--;
}
return tmp;
}