leetcode 力扣 19 删除链表的倒数第N个结点

60 阅读1分钟

思路:快慢指针,同步移动。

我们的目标是找到倒数第n个结点的前一个结点。

1 -> 2 -> 3 -> 4 -> 5

假设要删除倒数第3个结点,如果快指针位于5号位置,那么慢指针是不是应该位于2号位,才能把3删除。此时快慢指针相隔两个结点。

所以快慢指针应该相隔n-1个结点,再同步移动,直到快指针位于最后一个结点。

首先要解决链表如果只有一个结点的问题,所以需要一个dummy结点,插在头结点前。

慢指针指向dummy,快指针指向head。

快指针先移动n-1步,这时快慢指针相隔n-1个结点。

然后快慢指针同步移动,快指针到达最后一个结点时,慢指针删除它的下一个结点。

注意要返回dummy.next而不是head。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;

        ListNode fast = head;
        ListNode slow = dummy;

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

        while (fast.next != null) {
            fast = fast.next;
            slow = slow.next;
        }

        slow.next = slow.next.next;

        return dummy.next;
    }
}