题目描述
代码解决(双指针)
/** * 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) { ListNode*dummyHead=new ListNode(0); dummyHead->next=head; ListNode*fast=dummyHead; ListNode*slow=dummyHead; while(n--&&fast!=nullptr) { fast=fast->next; } fast=fast->next; while(fast!=nullptr) { fast=fast->next; slow=slow->next; } slow->next=slow->next->next; return dummyHead->next; } };
这段代码是一个用于删除单向链表中倒数第n个节点的函数。让我们逐行来解释一下:
ListNode
是一个单向链表节点的结构体或类,假设它有一个整型的val
成员和一个指向下一个节点的指针next
。
class Solution
定义了一个类,其中包含了公有的成员函数removeNthFromEnd
,该函数接收一个指向链表头部的指针head
和一个整数n
,表示要删除倒数第几个节点。
ListNode*dummyHead=new ListNode(0);
创建了一个值为0的虚拟头节点dummyHead
,这样做是为了方便处理边界情况,避免单独处理头节点的删除情况。
dummyHead->next=head;
将虚拟头节点的next
指针指向实际的链表头节点head
,这样做是为了保持链表的结构。
ListNode*fast=dummyHead;
和ListNode*slow=dummyHead;
创建了两个指针fast
和slow
,初始都指向虚拟头节点,用来找到要删除的节点位置。
while(n--&&fast!=nullptr)
是一个循环,条件是n
不为0且fast
不为空。循环内部让fast
指针往前移动,相当于让fast
指针领先slow
指针n
个节点。
fast=fast->next;
在上面的循环结束后,再额外往前移动一步,以便让fast
指向要删除节点的前一个节点,这样才能正确删除节点。接下来是第二个循环
while(fast!=nullptr)
,在这个循环中,fast
和slow
指针一起往前移动,直到fast
指向链表末尾的nullptr。
slow->next=slow->next->next;
这一行代码实际上删除了倒数第n
个节点。它将slow
指针的next
指针直接指向了要删除节点的下一个节点,跳过了要删除的节点。最后,
return dummyHead->next;
返回删除节点后的链表头节点,即实际链表的头节点。这段代码利用了快慢指针的方法,在一次遍历中完成了删除倒数第
n
个节点的操作,时间复杂度为O(N),其中N是链表的长度。