第一次做这道题的时候使用的方法是:先扫描链表一次统计其长度len,再使用一个指针遍历链表,从头节点向后走len-n-1步,恰好指向待删除节点的前一个节点再做处理。遇到待删除节点为头节点——即n==len的情况单独处理。
第二次做这道题时考虑最优算法,仅扫描链表一次的算法——使用快慢指针的思想,快指针先走一些步数慢指针再开始走,并且保持固定的距离。当快指针走到链表尾部的时候,慢指针恰好走到待删除节点的前一个节点。然后再使用以上方法删除待删除节点。需要注意的是头节点可能被删除,所以在处理问题之前先添加dummy node会使问题变得更容易处理。代码实现如下:
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode *dummy = new ListNode(-1);
dummy->next = head;
ListNode *slow = dummy,*fast = dummy;
while(n-->0)
fast = fast->next;
while(fast->next !=NULL){
fast = fast->next;
slow = slow->next;
}
ListNode *tmp = slow->next;
slow->next = tmp->next;
delete tmp;
return dummy->next;
}
};