leetcode 链接:删除链表的倒数第 N 个结点
题目
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
进阶:你能尝试使用一趟扫描实现吗?
示例:![[中等] 19. 删除链表的倒数第 N 个结点 - 图1](/uploads/projects/xf015y@ivbwyo/0d93bf2a0b760154ca632625e1f3bf18.jpeg)
输入:head = [1,2,3,4,5], n = 2输出:[1,2,3,5]
解答 & 代码
快指针先走 n 步,然后快慢指针同时走,直到快指针的 next 指向空,此时慢指针指向倒数第 k+1 个节点,删除倒数第 k 个节点
时间复杂度 O(N),空间复杂度 O(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) {
// 特殊情况:如果头节点为空或者 n<1 (n 代表要删除倒数第 n 个节点),不删除,直接返回原头节点
if(head == nullptr || n < 1)
return head;
ListNode* dummyHead = new ListNode(-1, head); // 虚拟头节点
ListNode* fast = dummyHead; // 快指针
ListNode* slow = dummyHead; // 慢指针
// 快指针先走 n 步
for(int i = 0; i < n; ++i)
{
if(fast == nullptr) // 如果快指针走到空,说明 n 大于链表长度,因此不删除直接返回
return head;
fast = fast->next;
}
// 快慢指针同时走,快指针的next走到空,代表慢指针走到倒数第 k+1 个节点
while(fast->next != nullptr)
{
fast = fast->next;
slow = slow->next;
}
// 此时 slow 走到倒数第 k-1 个节点
ListNode* kNode = slow->next; // 倒数第 k 个节点
slow->next = kNode->next;
delete kNode; // 删除倒数第 k 个节点
return dummyHead->next;
}
};
执行结果:
执行结果:通过
执行用时:4ms, 在所有 C++ 提交中击败了 82.82% 的用户
内存消耗:10.5 MB, 在所有 C++ 提交中击败了 20.71% 的用户
