原题链接:Leecode 19. 删除链表的倒数第 N 个结点
题目说了:希望我们一次扫描完成这道题,所以先遍历一遍链表求长度,再遍历一遍删除倒数第n个数肯定是不行的,但是不知道链表长度就无法知道倒数第n个结点在哪,这就是这道题需要思考的点。以下是我的代码,我设置了一个vector
数组,将每一个结点放入数组,数组是有下标的,所以遍历完一遍数组后就知道要删除的点在哪了,显而易见, 这个思路的缺点就是:会消耗额外的内存 。
/**
* 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* root=head;
vector<ListNode* > tmp={head};
int num=0;
while(head)
{
head=head->next;
num++;
tmp.push_back(head);
}
num=num-n;
if(!num)
return root->next;
tmp[num-1]->next=tmp[num+1];
return root;
}
};
那么有没有不用数组存储,又只扫描一遍的方法呢?有,我在别的大佬那里看到了下面这个代码,妙啊!妙不可言!:
/**
* 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* root=head;
ListNode* tmp=head;
while(head)
{
if(n<0)
tmp=tmp->next;
n--;
head=head->next;
}
if(!n)
return root->next;
tmp->next=tmp->next->next;
return root;
}
};