主要是我自己刷题的一些记录过程。如果有错可以指出哦,大家一起进步。
转载代码随想录
原文链接:
代码随想录
题目:
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
示例:
提示:
链表中结点的数目为 sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz
进阶:你能尝试使用一趟扫描实现吗?
思路:
双指针的经典应用,如果要删除倒数第n个节点,让fast移动n步,然后让fast和slow同时移动,直到fast指向链表末尾。删掉slow所指向的节点就可以了。
思路是这样的,但要注意一些细节。
分为如下几步:
首先这里我推荐大家使用虚拟头结点,这样方便处理删除实际头结点的逻辑。
定义fast指针和slow指针,初始值为虚拟头结点,如图:
fast首先走n + 1步 ,为什么是n+1呢,因为只有这样同时移动的时候slow才能指向删除节点的上一个节点(方便做删除操作),如图:
fast和slow同时移动,直到fast指向末尾,如题:
删除slow指向的下一个节点,如图:
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummyHead = new ListNode(0,head);
ListNode* slow = dummyHead;
ListNode* fast = dummyHead;
while(n-- && fast!= nullptr){
fast = fast->next;
}
fast = fast->next;// fast再提前走一步,因为需要让slow指向删除节点的上一个节点
while(fast !=nullptr){
fast=fast->next;
slow=slow->next;
}
slow->next = slow->next->next;
// ListNode *tmp = slow->next; C++释放内存的逻辑
// slow->next = tmp->next;
// delete tmp;
return dummyHead->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)
return head;
//统计节点个数
ListNode* cur = head;
int size = 0;
while (cur) {
++size;
cur = cur->next;
}
if (n == size) {
return head->next;
}
ListNode* pre = head;
int num = size - n;
while (--num) {
pre = pre->next;
}
//ListNode* temp = pre->next;
pre->next = pre->next->next;
//delete temp;
return head;
}
};