这题没遇到什么瓶颈……一开始没有考虑对头结点的处理,后来加上一个dummy之后就好了。
一开始是比较慢的二重循环的做法
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
if(head==NULL||head->next==NULL) return NULL;
int i=0;
ListNode* temp=head;
while(temp!=NULL){
i++;
temp=temp->next;
}
int m=i-n;
ListNode tmp(0);
tmp.next=head;
temp=&tmp;
for(int j=0;j<m;j++) temp=temp->next;
temp->next=temp->next->next;
return tmp.next;
}
};
看了别人的做法,可以设置两个指针,一个指针先移动到第n个结点,然后另一个指针开始同步移动直到第一个指针移动到最后。那么后移动的指针就移动了size-n次。
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
if(head==NULL||head->next==NULL) return NULL;
ListNode dummy(0);
dummy.next=head;
ListNode* t1=head;
for(int i=0;i<n;i++) t1=t1->next;
ListNode* t2=&dummy;
while(t1!=NULL){
t1=t1->next;
t2=t2->next;
}
t2->next=t2->next->next;
return dummy.next;//这里老是想返回head,但其实不可以
}
};
t1和t2之间存在一个节点的差距,即t1走到尾节点时,t2指向要删除的节点,但我们想让t2指向要删除的节点前一个节点该怎么做呢?
我一开始的做法是令t2初始化指向head,然后while(t1->next!=NULL), 但是这样做的话,当test case只有一个节点的时候,t1实际上是一个空指针,因此会出错。
正确的做法还是要判断while(t1!=NULL) 然后令t2初始化指向dummy就可以啦
还有一个问题是为什么不能直接返回head,是因为如果remove掉的是head的话,返回head会使结果错误。这也是设置dummy节点的目的。