19. Remove Nth Node From End of List
题目大意
Given the head of a linked list, remove the nth node from the end of the list and return its head.
中文释义
给定一个链表的头节点,移除链表末尾的第 n 个节点,并返回链表的头节点。
示例
Example 1:
Input: head = [1,2,3,4,5]
, n = 2
Output: [1,2,3,5]
Example 2:
Input: head = [1]
, n = 1
Output: []
Example 3:
Input: head = [1,2]
, n = 1
Output: [1]
限制条件
- 链表中的节点数为 sz。
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz
进阶问题
你能否只遍历一次完成此任务?
解题思路
方法
即从链表末尾移除第 n 个节点。方法使用双指针(快慢指针)技术,能够在一次遍历中完成任务。
-
使用哨兵节点:
- 创建一个哨兵节点
sentinel
并将其next
指向head
。
- 创建一个哨兵节点
-
初始化快慢指针:
- 创建两个指针
fast
和slow
,均指向哨兵节点。
- 创建两个指针
-
快指针先行:
- 移动快指针
fast
先前进n + 1
步,以确保快慢指针之间的间隔是n
个节点。
- 移动快指针
-
快慢指针同步移动:
- 同时移动快慢指针,直到快指针
fast
到达链表末尾。此时,慢指针slow
将指向待删除节点的前一个节点。
- 同时移动快慢指针,直到快指针
-
删除目标节点:
- 更新慢指针
slow
的next
指针,使其指向待删除节点的下一个节点,从而实现删除操作。
- 更新慢指针
-
返回结果:
- 返回哨兵节点
sentinel
的next
作为新链表的头节点。
- 返回哨兵节点
代码
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode sentinel(0);
sentinel.next = head;
ListNode *fast = &sentinel, *slow = &sentinel;
// 快指针先前进n+1步
for (int i = 0; i <= n; ++i) {
fast = fast->next;
}
// 快慢指针一起前进,直到快指针到达末尾
while (fast) {
slow = slow->next;
fast = fast->next;
}
// 删除节点
slow->next = slow->next->next;
return sentinel.next;
}
};