删除链表的倒数第 N 个结点

451 阅读2分钟

这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战

leetcode 删除链表的倒数第 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]

解题:首先要遍历链表,获取链表的长度,然后再根据链表长度和n找到要删除的节点上一个节点位置,就是要定位倒数n+1个节点位置,对于倒数n+1位置来说要删除的是倒数n位置的节点,那么只要把倒数n+1位置的下一个节点指向倒数n-1位置的节点,修改一下这个指针指向就可以完成删除倒数n位置的节点。

 public ListNode removeNthFromEnd(ListNode head, int n) {
        // 获取链表长度
        int length = 0;
        ListNode lenNode = new ListNode(0, head);
        while (lenNode.next != null) {
            length++;
            lenNode = lenNode.next;
        }
        // 这是要删第一个节点的节奏啊
        if (length - n - 1 == -1) {
            return head.next;
        }
        ListNode copyNode = head;
        // 从头到尾一直找到要删除的节点 的上一个节点
        for (int i = 0; i < length - n - 1; i++) {
            copyNode = copyNode.next;
        }
        // 删除那个节点 改变next指向
        copyNode.next = copyNode.next.next;
        return head;
    }

或者不获取链表长度,使用两个链表来遍历,需要删除倒数第n个位置,遍历两个链表时,使得这两个链表的当前位置相差为n,当一个链表遍历到最后时,另外一个链表的位置就是倒数第n个位置。先复制一个链表2,遍历原链表节点,直到遍历n位置,然后现在同时遍历原链表和链表2,直到原链表结束(没有下一个节点),此时链表2刚好走到倒数第n个节点,因为链表2头部加了个哑节点,所以链表2的当前位置就是倒数第n节点的前一个节点,再将链表2的当前下一个节点指向下下个节点,就删除了倒数第n个节点。

 public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode listNode = new ListNode(0, head);
        ListNode copyNode = listNode;
        // 先走一个 走到n位置为止
        for (int i = 0; i < n; i++) {
            head = head.next;
        }
        // 然后再一起走,直到先走的走到头为止
        // 这个时候后走的就走了链表长度-n的位置,因为后走的链表多个节点,所以刚好是要删除节点的前一个节点
        while (head != null) {
            head = head.next;
            copyNode = copyNode.next;
        }
        // 删除节点
        copyNode.next = copyNode.next.next;

        return listNode.next;
    }