4-2 代码随想录 第二章 链表part02 19.删除链表的倒数第 N 个结点(快慢指针)
例子解析:19. 删除链表的倒数第 N 个结点
19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)
问题描述
- 给定一个链表,删除链表的倒数第 n 个结点,并返回删除后的链表头节点。
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:
/**
* 删除链表的倒数第 n 个结点,并返回新的头节点。
* @param head 链表的头节点。
* @param n 倒数第 n 个结点的编号。
* @return 删除后的链表头节点。
*/
ListNode* removeNthFromEnd(ListNode* head, int n) {
// 创建一个虚拟头节点,避免处理头节点删除的特殊情况
ListNode *dummy = new ListNode(0);
dummy->next = head;
// 定义快慢指针,均初始化为虚拟头节点
ListNode *fast = dummy;
ListNode *slow = dummy;
// 快指针先前进 n 步
while (n-- && fast != nullptr) {
fast = fast->next;
}
// 快慢指针同时前进,直到快指针到达链表末尾
fast = fast->next;
while (fast != nullptr) {
fast = fast->next;
slow = slow->next;
}
// 删除慢指针后的节点,即倒数第 n 个节点
slow->next = slow->next->next;
// 返回新的头节点
return dummy->next;
}
};
代码解析
-
虚拟头节点:
- 使用虚拟头节点避免了处理头节点删除的特殊情况。
双指针法:
- 快指针先前进 n n n 个步,保证快慢指针之间间隔为 n n n 个。
- 快慢指针同步前进,当快指针到达链表末尾时,慢指针指向要删除节点的前一个节点。
- 删除慢指针后的节点,完成删除操作。
2 复杂度分析
| 方法 | 时间复杂度 | 空间复杂度 | 分析 |
|---|---|---|---|
| 双指针法 | O ( n ) O(n) O(n) | O ( 1 ) O(1) O(1) | 遍历链表两次,使用常数级别的额外空间。 |
详细解释
- 时间复杂度:
- 快指针需要先前进 n n n 步,然后与慢指针一起遍历剩余部分,因此时间复杂度为 O ( n ) O(n) O(n)。
- 空间复杂度:
- 只使用了常数级别的额外空间,即虚拟头节点和快慢指针,因此空间复杂度为 O ( 1 ) O(1) O(1)。
选择建议
- 适用场景:
- 适用于删除链表中倒数第 n n n 个节点的问题。
- 双指针法简化了代码逻辑,避免了计算链表长度的额外遍历。
这是 删除链表的倒数第 N 个结点 的解法,采用了 双指针法 实现。这种方法能够高效地找到并删除倒数第 n n n 个节点,并且代码逻辑简洁明了。
&spm=1001.2101.3001.5002&articleId=143136286&d=1&t=3&u=13b4df4012e44f5c967753b84b1f4e1a)
2万+

被折叠的 条评论
为什么被折叠?



