解题思路,举几个例子
1->1
1->1->2->2
1->2->2->3
1->2->2
思路也就清晰了:
循环遍历每个元素:
1、从头就开始重复的,head直接置为下一个跟头重复元素不同的结点,继续(当然可能还继续重复)
2、不从头重复的,考虑是去掉重复的所有元素,所以要多一个指针,指向重复的第一个结点的前一个
容易出错的地方:
1、判断循环的指针p是否为空 一定要先判断 eg:
while(p&& head->val==p->val)
在1->1的例子中,若p第二次循环时候已经为空,访问p的val当然会出错!
2、判断结束
1->2->2 也是类似,要先判断p是否已经结束,否则访问p的next也是错!
3、细节
eg:t最初是指向head的,所以head.val==t.val是必须的!
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
//重复的直接删除
ListNode *t=head;
if(t==NULL) return t;
if(t->next==NULL) return head;
//头可能重复
ListNode *pre=t;
ListNode *p=t->next;
while(p)
{
while(p&& head->val==p->val) //从头重复 但是,若p为空,再访问p的val就是有问题的!!!
//while(head->val==p->val && p) //所以注释掉这段
{
t=p;
p=p->next;
}
if(t->val==head->val && t!=head)//如果从头重复,直接head重新赋值
{
head=p;
}
if(p &&head->val!=p->val)//如果没有从头重复
{
while(p && t->val==p->val )//如果重复
{
p=p->next;
}
if(t->next==p)//如果没有重复
{
pre=t;
t=t->next;
p=p->next;
}
else//重复处理:
{
pre->next=p;
t=p;
if(p==NULL) break;//如果已经到最后 直接结束循环,否则再访问next肯定出错!
else p=p->next;
}
}
}
return head;
}
};