19. 删除链表的倒数第 N 个结点
力扣题目链接
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
示例 2:
输入:head = [1], n = 1
输出:[]
示例 3:
输入:head = [1,2], n = 1
输出:[1]
思路
难点:找到倒数第n个节点是哪个(单链表只能前进不能后退)
单链表要修改一个节点时,指针通常指向待处理节点的前一个节点处
方法1:先算出有多少个节点,再去找倒数第n个(缺点:要遍历两遍)
方法2:
例如:n=2,倒数第二个节点——4
- 设计两个指针fast、slow,初始位置为虚拟头节点
- fast先走n+1步(n+1=3)
- 后续两个指针一起前进,直到fast指向nullptr5. 因为两个指针相间n+1个节点,所以slow指向的为倒数n节点的前一个结点
- slow指向的节点删除后面一个节点
代码
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* _dummyhead=new ListNode(0,head);
ListNode* slow=_dummyhead;
ListNode* fast=_dummyhead;
n+=1;
while(fast!=nullptr&& n--)
{
fast=fast->next;
}
while(fast!=nullptr)
{
fast=fast->next;
slow=slow->next;
}
slow->next=slow->next->next;
return _dummyhead->next;
}
};
注意点
return 写_dummyhead->next
不要写return head,当[1],n=1时,输出应当为[ ],结果却为[1]
要考虑可能删除头节点的可能