题目描述
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
进阶:你能尝试使用一趟扫描实现吗?
样例描述
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
/**
* 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; }
* }
*/
思路
- 双指针。设置一个快指针和一个慢指针。让快指针先移动n个结点,然后快慢指针同时一起移动,当快指针指向空的时候,慢指针指向的结点就是倒数第n个结点。
- 删除慢指针所在的结点需要知道慢指针的前一个结点,可以另外设置一个指针每次记录下来。
- 设置一个虚拟头结点,让对头结点的操作与其他结点保持一致。 (因为可能要删除头结点)
代码
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
if (head == null) return head;
//链表题一般都需要虚拟头结点,这样对头结点的操作可以与其他结点保持一致
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode fast, slow, preSlow;
slow = head;
fast = head;
preSlow = dummy;
int i = 0;
while (i < n) {
fast = fast.next;
i ++;
}
while (fast != null) {
fast = fast.next;
preSlow = slow;
slow = slow.next;
}
preSlow.next = slow.next;
return dummy.next;
}
}