![](https://i-blog.csdnimg.cn/blog_migrate/9a0a01cecdd084b1a0debc1e049974b2.png)
![](https://i-blog.csdnimg.cn/blog_migrate/9484897d960c4cfdd8c9a4348524b968.png)
思路
由于单链表不能倒着遍历,这里我们借助快慢指针来找到链表的倒数第n个节点位置。
由于可能涉及头结点的删除,这里我们还是使用上虚拟头结点。
快慢指针法
起初,慢指针slow和快指针fast都指向虚拟头结点dummy,然后,我们让快指针先走n个节点。
接着让快指针和慢指针一起走,直到快指针指向尾节点,这时候慢指针的下一个位置就是要被删除的节点。
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
if (head == nullptr)
return nullptr;
//1.增加虚拟头节点
ListNode* dummy = new ListNode(-1);
ListNode* slow = dummy;
ListNode* fast = dummy;
dummy->next = head;
//2.快指针先走n步
while (n--)
{
fast = fast->next;
}
//3.快慢指针一起走,直到快指针指向尾节点
while (fast->next != nullptr)
{
fast = fast->next;
slow = slow->next;
}
//4.这是慢指针的下一个节点就是我们要删除的节点
ListNode* tmp = slow->next;
slow->next = tmp->next;
delete tmp;
//5.返回真实头结点
return dummy->next;
}
};