思路:快慢指针,同步移动。
我们的目标是找到倒数第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;
}
}