19. 删除链表的倒数第N个节点

两次遍历

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {

        /**
         * 两次遍历
         * 先得到链表的长度,再正向遍历到length - n的位置,也就是待删除节点的前一个节点
         */
        ListNode dummyHead = new ListNode(0, head);
        ListNode cur = dummyHead.next;
        int length = 0;

        while (cur != null){

            length++;
            cur = cur.next;
        }

        ListNode prev = dummyHead;

        for (int i = 0; i < length - n; i++) {
            prev = prev.next;
        }

        prev.next = prev.next.next;

        return dummyHead.next;
    }
}

/**
 * 时间复杂度 O(n)
 * 空间复杂度 O(1)
 */

双指针

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {

        /**
         * 一次遍历(双指针)
         * fast先右移n + 1步,slow再一起移动,直到fast == null,此时slow指向待删除节点的前一个节点
         */
        ListNode dummyHead = new ListNode(-1, head);
        ListNode fast = dummyHead;
        ListNode slow = dummyHead;

        for (int i = 0; i < n + 1; i++) {
            fast = fast.next;
        }

        while (fast != null){

            fast = fast.next;
            slow = slow.next;
        }

        slow.next = slow.next.next;

        return dummyHead.next;
    }
}

/**
 * 时间复杂度 O(n)
 * 空间复杂度 O(1)
 */

https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/

posted @ 2021-12-19 15:05  振袖秋枫问红叶  阅读(41)  评论(0)    收藏  举报