标签:tail ash 特殊 情况 分类 两个指针 一个 没有 避免
//第一种解法,遍历一次数长度,然后把头尾相连,再遍历一次
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* tem=head;
int len=0;
while(tem->next){ //这里得到的长度是真实长度-1
tem=tem->next;
len++;
}
if(len==0) return NULL;
if(len==1){
if(n==1){
head->next=NULL;
}
else head=head->next;
return head;
}
tem->next=head; //头尾相连
ListNode* tail=tem;
for( int i=0;i<len-n+1;i++){ //从最后一个节点出发,直到到达要删的节点的前一个;但如果要删的节点是表头,也不会移动
tem=tem->next;
}
ListNode* trash=tem->next; //要删的节点
tail->next=NULL; //如果要删的是最后一个,如果没有这句会把倒数第二个和头连成环
tem->next=trash->next;
if(trash==head) head=head->next;
tail->next=NULL;
return head;
}
};
//上面一种分类非常麻烦,而且其实就是两个pass,完全没必要
//避免麻烦的分类和涉及头尾的特殊情况,很好用的方法是链表头加一个空的node
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummy= new ListNode(0);
dummy->next=head;
ListNode* r=head;
int len=0;
while(r){
r=r->next;
len++;
}
r=dummy;
for(int i=0; i<len-n; i++){
r=r->next;
}
r->next=r->next->next;
return dummy->next;
}
};
//解法3, 用两个指针做遍历,第一个比第二个快n个节点,等第一个到达tail的时候,第二个就是要删的节点前一个。
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummy=new ListNode(0);
dummy->next=head;
ListNode *f=dummy, *s=dummy;
for(int i=0;i<n;i++){
f=f->next;
}
while(f->next){
f=f->next;
s=s->next;
}
s->next=s->next->next;
return dummy->next;
}
};
标签:tail ash 特殊 情况 分类 两个指针 一个 没有 避免
原文地址:https://www.cnblogs.com/rarecu/p/11520482.html