19. 删除链表的倒数第 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个数跳过。复杂度O(n)。

    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode root = new ListNode(0, head);
        int length = 0;
        while (head != null) {
            length++;
            head = head.next;
        }
        ListNode cur = root;
        for (int i = 1 ; i <= length - n ; i++) {
            cur = cur.next;
        }
        cur.next = cur.next.next;
        ListNode ans = root.next;
        return ans;
    }

栈运用:

通过栈原理,逆序获得倒数第n个数。复杂度O(n)。

    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode root = new ListNode(0, head);
        head = root;
        LinkedList<ListNode> list = new LinkedList<>();
        while (root != null) {
            list.add(root);
            root = root.next;
        }

        ListNode node = null;
        while (n > 1) {
            node = list.removeLast();
            n--;
        }
        list.removeLast();
        list.getLast().next = node;
        return head.next;
    }

双指针:

通过快慢指针,让l1和l2差n个,当l2为null时l1到达倒数第n个数。复杂度O(n)。

    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode l1 = head, l2 = head;
        int k = n;
        while (k-- > 0) {
            l2 = l2.next;
        }
        if (l2 == null) {
            return head.next;
        }
        while (l2.next!= null) {
            l1 = l1.next;
            l2 = l2.next;
        }
        l1.next = l1.next.next;
        return head;
    }

Categories:

No responses yet

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注