解答
双指针,不难,这里记录一下添加虚拟头节点,写代码的时候以为加一个虚拟头节点有点烦,其实代码很简单,否则需要if else判断
代码一
没有使用虚拟头节点,如果删除第一个节点(倒数第N个),需要判断prev是否为空
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
if(head->next == nullptr && n==1){
delete head;
return nullptr;
}
ListNode *right=head, *left=head, *prev=nullptr;
while(n-- && right!=nullptr){
right = right->next;
}
while(right != nullptr){
right = right->next;
prev = left;
left = left->next;
}
// delete left, 如果删除第一个节点(倒数第N个),此时prev==nullptr,需要特判
// 如果使用虚拟头节点就不用判断了
if(left == head) {
prev = left;
left = left->next;
delete prev;
head = left;
}
else{
prev->next = left->next;
delete left;
}
return head;
}
};
代码二
添加虚拟头节点
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
// 添加虚拟头节点,其实代码很少
ListNode* dummyHead = new ListNode(0);
dummyHead->next = head;
ListNode* slow = dummyHead;
ListNode* fast = dummyHead;
while(n-- && fast != NULL) {
fast = fast->next;
}
fast = fast->next; // fast再提前走一步,因为需要让slow指向删除节点的上一个节点
while (fast != NULL) {
fast = fast->next;
slow = slow->next;
}
slow->next = slow->next->next;
return dummyHead->next;
}
};