思路:快慢指针,快指针先走n步,然后慢指针和快指针同时走直到快指针走到尾端,此时慢指针指向要删除的结点的前导结点。注意在操作链表的过程中使用虚拟头结点dummy_head。

/**
 * 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* dummy_node=new ListNode{-1};
        dummy_node->next=head;
        ListNode* slow=dummy_node;
        ListNode* fast=dummy_node;
        while(n-- && fast->next!=nullptr) fast=fast->next;
        while(fast->next!=nullptr){
            slow=slow->next;
            fast=fast->next;
        }
        auto temp=slow->next;
        slow->next=slow->next->next;
        delete temp;
        return dummy_node->next;
    }
};