题目描述给你一个链表删除链表的倒数第n个结点并且返回链表的头结点。示例 1输入head [1,2,3,4,5], n 2输出[1,2,3,5]示例 2输入head [1], n 1输出[]示例 3输入head [1,2], n 1输出[1]解题思路方法一暴力解法我的思路先把链表的值按顺序存入 vector删除倒数第 n 个再用剩下的值重建一个新链表。具体步骤边界处理如果链表只有一个节点直接返回nullptr取值遍历链表把所有值存入temp删除从temp中删除倒数第 n 个重建用temp中的值新建链表节点连接成新链表返回返回新链表的头节点用例子走一遍head 1 - 2 - 3 - 4 - 5,n 2步骤操作结果1遍历链表temp [1, 2, 3, 4, 5]2删除倒数第2个下标 5-23temp [1, 2, 3, 5]3重建链表1 - 2 - 3 - 54返回1 - 2 - 3 - 5✅代码实现class Solution { public: ListNode* removeNthFromEnd(ListNode* head, int n) { if(head-nextnullptr) return nullptr; vectorint temp; while(head!nullptr){ temp.push_back(head-val); headhead-next; } temp.erase(temp.begin() (temp.size() - n)); ListNode* hnullptr; ListNode* tnullptr; for(int x:temp){ ListNode* nodenew ListNode(x); if(hnullptr){ hnode; tnode; } else{ t-nextnode; tnode; } } return h; } };复杂度分析维度复杂度说明时间复杂度O(n)遍历链表一次 O(n) 重建链表一次 O(n)空间复杂度O(n)temp存储 n 个值 新建 n-1 个节点缺点❌空间复杂度 O(n)需要额外存储所有值和新建所有节点❌没有利用链表的特性链表题应该用指针操作而不是转成数组方法二快慢指针O(1) 空间核心思路fast先走n1步fast和slow同时走当fast到末尾时slow正好在要删除节点的前一个直接slow-next slow-next-next完成删除代码实现class Solution { public: ListNode* removeNthFromEnd(ListNode* head, int n) { ListNode* dummy new ListNode(0); dummy-next head; ListNode* fast dummy; ListNode* slow dummy; // fast 先走 n1 步 for (int i 0; i n; i) { fast fast-next; } // fast 和 slow 同时走 while (fast ! nullptr) { fast fast-next; slow slow-next; } // 删除 slow-next slow-next slow-next-next; return dummy-next; } };复杂度时间 O(n)空间 O(1)两种方法的对比对比维度暴力解法最优解法快慢指针时间复杂度O(n)O(n)空间复杂度O(n)O(1)是否新建节点✅ 需要 new n-1 个❌ 不需要是否修改原链表❌ 不修改✅ 修改代码长度较长中等