力扣题目19:删除链表的倒数第N个结点
同样采用虚拟头结点的方法(方便对于头结点的处理)。
如图所示,n=2时即为删除倒数第二个结点(4结点)。该题的关键是根据n怎么找到需要删除的结点 。
可以采用双指针法来控制两个指针之间的距离来找到需要删除的结点。一开始fast和slow均指向dummyNode,根据n将fast进行移动。
n=2,即将fast移动两次,此时fast指向2结点。然后开始进行循环,直至fast指向最后一个结点(5结点),同时移动slow结点。
此时,fast指向最后一个结点(5结点);slow指向要删除结点的前驱结点(3结点)。然后将slow的next指向slow->next->next(5结点),再将4结点delete掉即可完成删除。
note:注意不能直接让slow的next指向fast,因为如果要删除的元素是最后一个元素,就会出问题。本题中只是一个例外,fast刚好为slow->next->next。fast在循环结束始终指向末尾元素。
本题的关键就是采用快慢指针之间的距离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* dummyNode = new ListNode(0);
dummyNode->next = head;//初始化虚拟头结点
ListNode* slow = dummyNode;
ListNode* fast = dummyNode;//初始化快慢指针均指向虚拟头结点
while (n--)
fast = fast->next;
while (fast->next) {
slow = slow->next;
fast = fast->next;
}
ListNode* temp = slow->next;
slow->next = temp->next;
delete temp;
return dummyNode->next;
}
};