leetcode每日一题-「删除链表倒数第N个节点」

249 阅读1分钟

【题目标题】

删除链表倒数第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链接起来。

image.png

【代码实现】

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;
    }
}