题目要求
删除链表中重复的结点__牛客网 (nowcoder.com)
思路:
-
如果链表为空 或者 链表只有一个结点 ,直接返回链表的头结点 -
注意: 要定义三个指针
-
- 初始:prev = NULL cur = Phead next = cur -> next
-
通过next 指针遍历链表,注意:不是通过cur指针。next指针比cur指针更快到达NULL。next指针找和cur指向结点的值不相同的位置 -
如果找到了cur结点和next结点值不相等的位置 -> prev cur next 都迭代往后走,只有cur和next一起移动,prev才跟着移动
-
否则(cur结点和next结点值相等): 让next一直往后走,直到找到next结点的值和cur结点值不相同的位置
-
若曾经出现next->val == cur->val 情况时:当next找到和cur指向结点不相同的结点后.释放从[cur , next)区间的结点
-
释放完成后,next指向cur的下一个结点,继续找重复结点
-
最后返回Phead头结点
总结:
- 定义三个指针,cur prev next,初始:prev = NULL cur = Phead next = Phead ->next
- 当next为空时,循环结束
- 如果cur->val != next ->val 三个指针一起移动
- 如果cur -> val == next -> val
- next一直往后走,直到找到cur -> val != next->val 的位置 (注意:要防止next为空)
- 找到了之后,要先判断此时的prev是否为空
- 若prev为空:说明要更改头指针的指向
- 若prev不为空:要更改prev的next的指向 prev->next = next;
- 用cur遍历,释放[cur,next)区间的结点,释放完成后,cur 指向的时next位置
- 判断此时next是否为空
- 如果next ==NULL :说明可以直接跳出循环了,break 也可以不写,通过下一次进入循环判断时结束
- 如果next不为空:next指向cur的下一个结点。开启下一轮比较
- 最后返回Phead
当所有结点都是重复的:
代码:
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if(pHead == NULL || pHead ->next == NULL)
{
return pHead;
}
ListNode* prev = NULL;
ListNode* cur = pHead;
ListNode* next = cur->next;
while(next)
{
if(cur->val != next->val)
{
prev = cur;
cur = next;
next = next->next;
}
else
{
while(next&& cur->val == next->val )
{
next = next->next;
}
if(prev)
{
prev -> next = next;
}
else
{
pHead = next;
}
while(cur != next)
{
ListNode* del = cur;
cur = cur->next ;
free(del);
}
if(next)
{
next = cur->next;
}
}
}
return pHead;
}
};
|