【题目标题】
删除链表倒数第N个节点
【题目描述】
给你一个链表,删除链表的倒数第 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]
提示: 链表中结点的数目为 sz 1 <= sz <= 30 0 <= Node.val <= 100 1 <= n <= sz
【解题思路】
【双指针法】
本题的难点是找到链表的倒数第n个节点。我们知道链表只有遍历到上个节点才能知道下个节点的位置,链表的尾节点的下一节点为空。因为是倒数第n个节点位置,通过正向推导肯定是不可行的,逆向的标志位我们只知道什么时候到了尾结点。鉴于此,可以通过快慢两个指针,快指针先正向走n个位置,然后慢指针从第一个位置出发。当快指针达到尾节点时,那慢指针刚好达到了倒数第n个节点。
同时因为需要删除倒数第n个节点,所以我们需要知道倒数第n+1个位置,这样才能将倒数n+1和倒数n-1链接起来。
【代码实现】
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode fast = head;
ListNode slow = head;
ListNode slowPre = head;
int i = 0;
while (fast != null) {
if (i >= n) {
slow = slow.next;
}
if (i >= n+1) {
slowPre = slowPre.next;
}
fast = fast.next;
i++;
}
//考虑n=链表长度的情况
if (slow==head) {
ListNode newHead = slow.next;
slow.next = null;
return newHead;
} else {
slowPre.next = slowPre.next.next;
return head;
}
}