题目
给你一个链表,删除链表的倒数第 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]
/**
* 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 dummy(-1,head);
ListNode *fast = &dummy, *slow = &dummy;//两个指针指向头节点
//fast先走n步,指向第n个节点
for(int i=0; i<n; i++)
fast = fast->next;
//当fast的后继不为空时,fast和slow一起走
while(fast->next){
fast = fast->next;
slow = slow->next;
}
//while循环结束时fast指向链表的最后一个节点,slow指向链表的倒数第n+1个节点
//删除倒数第n个节点
ListNode *tmp = slow->next;
slow->next = slow->next->next;
delete tmp;
return dummy.next;
}
};
- 时间复杂度O(n)
- 空间复杂度O(1)
- 思路
- 设置一个头节点,初始化两个指针指向头节点,指针fast先走n步,然后二者一起走,直到指针fast走到链表的最后一个节点。此时slow在链表的倒数第n+1个节点。
- 删除slow的后继节点,返回头节点的后继节点。