只是需要删除重复的多余结点,保留1个就行。
大致思路:
只需要在当前结点来进行处理就行,因为只是删除多余的,也不用担心头结点会被删去导致返回的不对的错误。一次AC。
AC代码:
class Solution {
public:
ListNode *deleteDuplicates(ListNode *head) {
//看结点后面的值是不是一样,一样就跳过,直到不一样,连起来
if(head==NULL)
return NULL;
if(head->next==NULL)
return head;
ListNode *p = head;
while(p!=NULL)
{
int temp = p->val;
ListNode *cur = p;
while(p->next!=NULL && p->next->val==temp)
{
p = p->next;
}
cur->next = p->next;
p = p->next;
}
return head;
}
};
加强版II
不仅删除多余的,还要把具有重复的结点自身给删除了。
大致思路:
难度在于有可能头结点就是重复的所以头结点就没了呢,导致不知道返回什么,找不到合适的用来返回的指针。
我刚开始的做法是讨论头结点是不是重复,从而据情况修改返回的指针,事实证明这样真的很麻烦!后来看题解,理解到一种比较“方便实用”的方法:
对于这种涉及链表删除而且可能改变头结点的,一定要“建新头”,新头->next=原头,最终返回的是新头->next。两个指针slow和fast,slow从新头开始,fast从原头开始,根据fast的情况修改slow和slow->next,即借助fast来修改slow,重新组织新头带领的链表的逻辑顺序。
因为建了新头之后啊,你就可以不把原头当头结点看了,它没有,没事,我返回的是新头->next也就是正确的结果头;它还在,可以的,新头->next仍是原头,返回的也是对的。
AC代码(重要!必须吃透!):
class Solution {
public:
ListNode *deleteDuplicates(ListNode *head) {
//看结点后面的值是不是一样,一样就跳过,直到不一样,连起来
if(head==NULL)
return NULL;
if(head->next==NULL)
return head;
ListNode *fast = head;
ListNode *real_head = new ListNode(0);
real_head->next = head;
ListNode *slow = real_head;
while(fast && fast->next)
{
if(fast->val == fast->next->val)
{
while(fast->next && fast->val==fast->next->val)
fast = fast->next;
slow->next=fast->next;
}
else
slow = fast;
fast = fast->next;
}
return real_head->next;
}
};