题目描述
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
示例 1:
输入:head = [1,2,3,4,5], n = 2 输出:[1,2,3,5]
示例 2:
输入:head = [1], n = 1 输出:[]
示例 3:
输入:head = [1,2], n = 1 输出:[1]
提示:
链表中结点的数目为 sz 1 next;//返回新链表即可 } };
进阶要求我们扫描一次实现,想了半天没想出来,看了题解才知道要用双指针。双指针雀氏是一种非常妙的解法,没遇到这种题还真不好想出来。这道题用双指针就是用了一个前后指针,我们创建两个指针,一个前指针first,一个后指针second,我们让first超过second指针n个结点,那么first指针遍历到链表结尾的时候,second指针刚好就在倒数第n个结点,这样一次遍历是可以实现了。
代码实现/**
* 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* p=new ListNode();
p->next=head;
ListNode* first=head;
ListNode* second=p;
for(int i=0;inext;
}
while(first)
{
first=first->next;
second=second->next;
}
second->next=second->next->next;
return p->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) {
int ans=find(head,n);
if(ans==n)
return head->next;
else
return head;
}
int find(ListNode* node,int n)
{
if(node==nullptr)
{
return 0;
}
int res=find(node->next,n);
if(res==n)
{
node->next=node->next->next;
}
return res+1;
}
};