/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 */

class Solution {
public:
    /**
     * 
     * @param head ListNode类 
     * @param n int整型 
     * @return ListNode类
     */
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode *dummyhead = new ListNode(0);
        dummyhead->next = head;
        ListNode *tmp = head;
        for (int i = 0; i < n; ++i) {
            tmp = tmp->next;
        }
        ListNode *bef = dummyhead;
        while (tmp) {
            tmp = tmp->next;
            bef = bef->next;
        }
        ListNode *nxt = bef->next;
        bef->next = bef->next->next;
        delete nxt;
        return dummyhead->next;
    }
};

可以先遍历一遍计算出链表长度,然后再计算出正数的节点位置,进行删除。

一遍遍历删除的思路:先用fast指针找到正数第k个,然后用slow指针指向头部,与fast指针同时移动,这样fast指针移动到最后一个节点,slow指针就会指向倒数第k个。

* 删除节点需要找到该节点的上一个节点bef,我们要把slow当作bef,所以slow要往前一位。

* 然而head不能再往前一位了,所以用一个dummyhead作为虚假头节点。

* dummyhead还有个好处,就是如果删除的是head,不需要额外处理指向新的head。