一开始想太简单了没有考虑到已经遍历到的结点无法删除
看了答案区大佬的代码
有三种方法:
1.在原表基础上删除 要定义指向当前结点前一结点的指针
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode *p=head;//当前判断结点
ListNode *k=p;//p的前一个
while(p)
{
if(p->val==val)
{
if(p==head)//头要删
{
head=p->next;//
p=head;
if(head==NULL)
return head;
else continue;
}
else if(p->next==NULL)//尾
{
k->next=NULL;
return head;
}
else//中间
{
k->next=p->next;
p=k->next;
continue;
}
}
k=p;//k向前
p=p->next;//
}
return head;
}
};
2.另建新表 不等的放入新表
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode *p=new ListNode(-1);//预先指针
ListNode *l1=p;//当前指针
while(head)
{
if(head->val==val)//相等 舍弃
head=head->next;
else{
ListNode *c=new ListNode(head->val);//不等的加入新表
l1->next=c;
l1=l1->next;
head=head->next;
}
}
return p->next;
}
};
3.递归
递归很棒 但易错
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
if(!head)
return head;
head->next=removeElements(head->next,val);
return head->val==val?head->next:head;//相等舍弃
}
};
三种方法整体效率对比:
提交记录区还能看到更多效率更高的算法