题目
思路
看到倒数第N个这种题目,马上就想到的是双指针:
快指针比慢指针先跑N步,快慢指针再一起跑,待快指针到链表尾部,慢指针不就到末尾了嘛。
关键因素
题目是删除倒数第N个节点,那么单向链表删除节点必然是要获得被删除节点的前一个节点,然后:
pNode->next = pNode->next->next;搞定。
这时候,就意味着需要把快指针先跑步,才能拿到待删除节点的前驱。
链表头节点没有前驱!!!
需要在题目中增加一个虚拟头节点。
总结
思路是一点就会,但是链表的删改加个头节点使操作统一真的非常有必要!
实现
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
if (!head || (head->next == nullptr && n == 1)) { return nullptr; }
ListNode vHead;
vHead.next = head;
ListNode* tail = &vHead;
int count = 0;
while (count++ < (n + 1)) {
if (tail == nullptr) { break; }
tail = tail->next;
}
ListNode* pDeleteNextLater = &vHead;
while(tail != nullptr) {
tail = tail->next;
pDeleteNextLater = pDeleteNextLater->next;
}
pDeleteNextLater->next = pDeleteNextLater->next->next;
return vHead.next;
}
};