一、介绍
1.题目描述
题目链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/
给你一个链表,删除链表的倒数第 n
个结点,并且返回链表的头结点。
进阶:你能尝试使用一趟扫描实现吗?
2.测试样例
[1,2,3,4,5]
2
# [1,2,3,5]
[1,2]
1
# [1]
[1]
1
# []
二、题解
1、暴力
暴力就不写了,直接一遍遍历计算链表长度,第二次遍历删除第 n 个节点
2、双指针🟢
定义 p q两个头尾指针,q先移动 n 个节点
- 如果q移动完已经在末尾,说明 n = 链表长度,删除第一个节点。
然后pq一起遍历直到q达到末尾。此时, p 的下一个节点即为要删除的节点
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode *p=head,*q=head;
while(n--)q=q->next;
// 如果 n 等于链表长度,则删除第一个元素
if(q==nullptr) return head->next;
// p q 同时移动,直到q到达末尾
while(q->next!=nullptr){
q=q->next;
p=p->next;
}
// 否则删除 p 的下一个元素
p->next=p->next->next;
return head;
}
};
3、栈🔴
1、创建一个栈,将所有节点依次入栈。
2、弹出 n 个节点,最后弹出的节点应该被删掉
- 如果弹出 n 个后栈为空,说明删除第一个节点
- 如果不空,则删除当前栈顶的下一个节点
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
stack<ListNode*> stk;
ListNode *p=head;
// 入栈
while(p!=nullptr) {
stk.push(p);
p=p->next;
}
// 出栈 n 个元素,最后栈的元素应该被删掉
while(n--) stk.pop();
// 如果栈为空,说明删除第一个节点
if(stk.empty()) return head->next;
// 否则,将当前栈顶的下一个节点删除
p=stk.top();
p->next=p->next->next;
return head;
}
};