19. 删除链表的倒数第 N 个结点
做题思路 or 感想:
1,用的还是快慢指针,不得不说我一开始真的没想到用快慢指针卡成一个“直尺”这样去找前n的元素,真的太秒了这个思路
2,这里是需要虚拟头节点的,只要有删除操作都需要,因为头节点也可能是删除目标
3,这里的快指针最后是要指向 nullptr 的,不能指向一个最后一个节点,为了打消链表中只有一个元素时的情况,太秒了
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode() : val(0), next(nullptr) {} 7 * ListNode(int x) : val(x), next(nullptr) {} 8 * ListNode(int x, ListNode *next) : val(x), next(next) {} 9 * }; 10 */ 11 class Solution { 12 public: 13 ListNode* removeNthFromEnd(ListNode* head, int n) { 14 if (head == nullptr) return nullptr; //防止奇怪测试用例 15 ListNode* dummyHead = new ListNode(0); //构建虚拟头节点 16 dummyHead->next = head; 17 ListNode* slow = dummyHead; 18 ListNode* fast = dummyHead; 19 while (n-- && fast->next != nullptr) { //先让fast先动 20 fast = fast->next; 21 } 22 fast = fast->next; //为了让slow指向的是目标节点的前一个节点,方便删除操作 23 while (fast != nullptr) { //最终是要让fast指向虚无的nullptr的,而不是让他指向最后一个节点,这样可以防止链表只有一个节点的情况 24 fast = fast->next; 25 slow = slow->next; 26 } 27 ListNode* temp = slow->next; 28 slow->next = slow->next->next; 29 delete temp; 30 return dummyHead->next; //这里细中细,因为如果链表只有节点,删完后head所指向的就丢失掉了,而这个时候只能用虚拟头节点的next来解决了 31 } 32 };