题目描述
给定一个链表,删除链表的倒数第 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
解题思路
- 用到双指针的解题方法;
- 删除节点是不是真的删除,只需将待删除节点的前一个结点的 next 指向待删除结点的下一个节点。
代码
/**
* 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 *front, *back; // 定义双指针
front = head;
back = head;
int i = 0;
// 将 front 指针移动到链表的第 n+1 个节点
while(i < n){
front = front->next;
if(front == NULL){ // 如果 front 指针指向 NULL,进行判断
if(i == n-1){ // 此时刚好是链表的第 n 个节点,则题目准备删除的是链表的第一个节点
return head->next; // 返回头节点以后的链表
}
return NULL; // 其他特殊情况下返回 NULL
}
i++;
}
// 将 front 指针和 back 指针同时向后移动
// 只到 front 指针指向链表最后一个元素
while(front->next){
back = back->next;
front = front->next;
}
// 此时 back 指向的节点的下一个节点就是要删除的节点,将它从链表上剔除
back->next = back->next->next;
// 返回链表
return head;
}
};
提交结果
总结
- 双指针的解题思路,只需将链表遍历一遍即可。