题目描述
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
进阶:你能尝试使用一趟扫描实现吗?
示例1
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
思路
这道题是双指针的经典应用
- 首先定义一个虚拟节点,它指向链表的头节点head
- 定义双指针 fast 和 slow,均初始化为虚拟节点
- fast 向后移动 n 个位置
- fast 和 slow 同时向后移动,直至 fast 到达链表的尾部, 此时 slow 就到达了倒数第 n 个节点的位置
- 要想删除 slow 所在位置的节点,要用到虚拟节点
- 详细过程见代码
代码
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode pre = new ListNode();
pre.next = head;
ListNode fast = pre;
ListNode slow = pre;
while(n > 0 && fast != null) {
n--;
fast = fast.next;
}
ListNode prev = null;
while(fast != null) {
prev = slow;
fast = fast.next;
slow = slow.next;
}
prev.next = slow.next;
return pre.next; // 注意这里不能是返回head,因为有可能head是要被删除的节点
}
}
复杂度分析
时间复杂度:O(n),其中n是链表中节点的数目
空间复杂度:O(1)