总览
解法1 扫描两轮
解法2 扫描一轮
快慢指针逻辑
快慢指针原理是设计两个指针,初始位置都在头结点处,如下图所示方法遍历一轮后,慢指针位置可以到达倒数第k位(但本题要找倒数第k+1位)。
虚拟头结点的使用
对不带头结点的链表使用虚拟头结点:
//虚拟头结点
ListNode* vp=new ListNode();
vp->next=head;
好处如下:
cpp代码
代码展示:
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
//虚拟头结点
ListNode* vp=new ListNode();
vp->next=head;
//快慢指针
ListNode* slow=vp;
ListNode* fast=vp;
//删除倒数第n,要找到倒数第n+1
//对于只有n个节点的链表,访问倒数第n+1会访问空指针,因此此题快慢指针初始位置为虚拟头结点vp
for(int i=0;i<n+1&&fast!=NULL;i++){
fast=fast->next;
}
while(fast!=NULL){
fast=fast->next;
slow=slow->next;
}
//删除操作
slow->next=slow->next->next;
return vp->next;
}
};
值得注意的是:
1.未进行delete操作力扣不会不让过,甚至可以缩减运行时间。
2.虽然扫描一轮理论上时间复杂度更低,但是本题力扣统计运行时间更少的算法是扫描两轮。