题目描述:
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针
例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
思路分析:
1.三指针法,创建三个指针,第一个作为我们自己创建的头节点,第二个和第三个负责找出重复的区间
2.遍历的终止条件是第三个指针为空,当第二个指针所在节点的值与第三个指针所在节点的值相等,说明重复,第二个指针不动,第三个指针继续往后走,它们的值不相等时,说明已经找到重复的区间
3.删除操作,将头节点的next指向第二个指针的next,将此时的第二个指针free然后置空,重复操作,直到第二个指针与第三个指针重合,说明全部删除关闭
4.新创建一个head,指向我们创建的头节点的next,将我们创建的头节点free置空防止内存泄漏
5.返回head指向的链表
6.注意极端情况:
<1>链表可能为空,或者链表只有一个节点
<2>链表可能全都是重复的
<3>链表可能一开始就是重复的
<4>删除完之后,链表可能还没有遍历完,第三个节点应该继续往后走
<5>申请的内存空间用完及时释放,避免内存泄漏
代码实现:
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if (pHead == NULL || pHead->next == NULL)
{
return pHead;
}
ListNode* first =(ListNode*)malloc(sizeof(ListNode));
first->next=pHead;
ListNode* newhead=first;
ListNode* mid = pHead;
ListNode* second=pHead->next;
while(second!=NULL)
{
while (second!=NULL&&mid->val==second->val)
{
second=second->next;
}
//中间有空隙,说明中间有重复区间
if (mid->next!=second)
{
while (mid!= second)
{
first->next=mid->next;
free(mid);
mid=NULL;
mid=first->next;
}
if(second!=NULL)
{
second=second->next;
}
}
else
{
first=mid;
second=second->next;
mid=mid->next;
}
}
ListNode* head=newhead->next;
free(newhead);
newhead=NULL;
return head;
}
};