给你一个链表,删除链表的倒数第 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
<
=
s
z
<
=
30
1 <= sz <= 30
1<=sz<=30
0
<
=
N
o
d
e
.
v
a
l
<
=
100
0 <= Node.val <= 100
0<=Node.val<=100
1
<
=
n
<
=
s
z
1 <= n <= sz
1<=n<=sz
进阶: 你能尝试使用一趟扫描实现吗?
解法一:
- 遍历链表,用数组记录每一个元素
- 遍历完成后删除倒数第 n 个元素(正数第 m - 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) {
vector<ListNode*> v;
ListNode* cur = head;
while(cur != nullptr){
v.push_back(cur);
cur = cur -> next;
}
int m = v.size();
if(n == m) return head -> next;
ListNode* pre = v[m - n - 1];
if(pre != nullptr) pre -> next = pre -> next -> next;
return head;
}
};
解法二:
- 快慢指针
- 快指针先往前走 n 个元素,慢指针指向头部元素
- 然后快慢指针一起往前走
- 当快指针指向 nullptr 时,慢指针恰好指向需要被删元素的上一个元素
- 指向删除即可
/**
* 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) {
vector<ListNode*> v;
ListNode* cur = head;
while(cur != nullptr){
v.push_back(cur);
cur = cur -> next;
}
int m = v.size();
if(n == m) return head -> next;
ListNode* pre = v[m - n - 1];
if(pre != nullptr) pre -> next = pre -> next -> next;
return head;
}
};