【9.删除链表的倒数第 N 个结点】

23 阅读1分钟

题目

给你一个链表,删除链表的倒数第 n **个结点,并且返回链表的头结点。

示例 1:

输入: head = [1,2,3,4,5], n = 2
输出: [1,2,3,5]

题解

方式一:双指针 + 虚拟节点

复杂度:O(n)遍历链表

// 找到要删除的节点,链表只能遍历
public ListNode removeNthFromEnd(ListNode head, int n) {
    // 虚拟节点,方便删除第一个节点
    ListNode dummy = new ListNode();
    dummy.next = head;
    ListNode slow = dummy;
    ListNode fast = dummy;
    // 快指针先走n步
    for (int i = 0; i < n; i++) {
        fast = fast.next;
    }
    // 快指针走到最后一个节点
    while (fast.next != null) {
        slow = slow.next;
        fast = fast.next;
    }
    // 此时,slow.next就是要删除的节点
    slow.next = slow.next.next;
    return dummy.next;
}

方式二:栈

复杂度:O(n),额外多了O(n)的空间——栈

public ListNode removeNthFromEnd(ListNode head, int n) {
    ListNode dummy = new ListNode();
    dummy.next = head;
    Deque<ListNode> deque = new LinkedList<>();
    ListNode cur = dummy;
    // 包括虚拟节点全部入栈
    while (cur != null) {
        deque.addLast(cur);
        cur = cur.next;
    }
    // 出栈n个元素
    for (int i = 0; i < n; i++) {
        deque.pollLast();
    }
    // 此时,栈顶是要删除元素的前一个节点
    ListNode pre = deque.getLast();
    pre.next = pre.next.next;
    return dummy.next;
}

总结

数据结构:
算法:双指针