题目:
思想:
- 两次遍历:第一次遍历得到总长度,第二次遍历删除节点
- 递归:递归到链表最后,等回退的时候,删除节点
- 双指针:一次遍历,O(2n),推荐
注意:
本题中需要注意的点,就是一个删除的节点是第一个节点的时候,需要额外判断一下。
递归:
/**
* 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:
void dfs(ListNode* &node,int& i,ListNode* pre,ListNode* &next,int n){
if(node == nullptr){
i=0;
next = NULL;
return ;
}
dfs(node->next,i,node,next,n);
i++;
if(i==n){
if(pre == nullptr){
node = node->next;
}else{
pre->next = next;
}
}
next = node;
return ;
}
ListNode* removeNthFromEnd(ListNode* head, int n) {
if(!head)return nullptr;
int i;
ListNode* next;
dfs(head,i,NULL,next,n);
return head;
}
};
双指针:
其实在注意到,题目中给的链表的构造函数的时候,就应该想到需要一个附加节点,也就是头节点,然后就能够想到需要双指针做法。
/**
* 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* dummy = new ListNode(0,head);
ListNode *first = head,*second = dummy;
for(int i=0;i<n-1;i++){
first = first -> next;
}
while(first -> next !=NULL){
second = second->next;
first = first -> next;
}
if(second == dummy){
head = head ->next;
}else{
second->next = second ->next ->next;
}
return head;
}
};
当然对于删除head的做法,还有更好的:
/**
* 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* dummy = new ListNode(0,head);
ListNode *first = head,*second = dummy;
for(int i=0;i<n-1;i++){
first = first -> next;
}
while(first -> next !=NULL){
second = second->next;
first = first -> next;
}
second->next = second ->next ->next;
return dummy -> next;
}
};