题目
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
示例 1:
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
示例 2:
输入:head = [1], n = 1
输出:[]
示例 3:
输入:head = [1,2], n = 1
输出:[1]
提示:
链表中结点的数目为 sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz
解析
为什么还是需要定义虚拟头节点?
在执行删除操作的时候,如果该点不是头结点的话,让该节点的前一个节点,指向该节点的后一个节点即可,如果时头结点的话,需要的操作就是head=head->next;
怎么找到倒数第N个节点?
删除倒数第N个节点就要找到倒数第N+1个节点,定义快慢指针吗,让快指针先走N+1步,之后,快慢指针一起走,指导快指针为空,这样慢指针就指到了倒数第N+1个节点
怎么执行删除操作?
让节点指向他的下一个下一个节点,就删掉了下一个节点,如图所示
代码
/**
* 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 *dynamicHead=new ListNode(0);
dynamicHead->next=head;
// 删除一个节点需要知道他的前一个节点,所以就让n多走一步,使用一个快指针和一个慢指针,
// 快指针先走n+1步,之后快指针和慢指针一起走,就可以找打倒数第n个
ListNode *fast=dynamicHead;
ListNode *slow=dynamicHead;
n++;
// 快指针先走n步
while(n--&&fast!=nullptr){
fast=fast->next;
}
// 快慢指针一起走
while(fast!=nullptr){
fast=fast->next;
slow=slow->next;
}
// 执行删除操作
slow->next=slow->next->next;
return dynamicHead->next;
}
};