解题思路
首先需要一个虚拟头结点指向头结点,然后有两个指针,分别是快指针和慢指针,初始时快指针和慢指针均指向头节点。我们首先使用快指针对链表进行遍历,遍历的次数为 n 。此时,快指针和慢指针之间间隔了 n-1 个节点,即快指针比慢指针超前了 n 个节点。在这之后,我们同时使用快指针和慢指针对链表进行遍历。当快指针遍历到链表的末尾(即快指针为空指针)时,慢指针恰好指向倒数第 n 个节点。之后就可以通过改变慢指针指向结点的指针域为该结点原指向的结点的指针域即可完成删除操作。最后返回的是虚拟头结点的指针域,记得要释放虚拟头结点。
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* fakehead=new ListNode(0,head);
ListNode* fast=head;
ListNode* slow=fakehead;
for(int i=0;i<n;i++){
fast=fast->next;
}
while(fast){
fast=fast->next;
slow=slow->next;
}
slow->next=slow->next->next;
ListNode* ans=fakehead->next;
delete fakehead;
return ans;
}
};
AC截图