-
题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5。
-
思路分析
我们可以给定两个一前一后的指针n1,n2,当两个指针的val不一样时,不需要处理,直到一样时,n1不动,让第二个指针n2往后走,走到跟n2不相同的地方,把n1和n2之间的数字删掉,再想办法把n1和n2链接起来,只要遇到相同的,就又重复前面的逻辑,这里还有一个问题要注意,就是删除时,得有它的前一个指针,所以还得有一个指针永远记录n1的前一个。
(补充一个简单的链表的去重:如果是有n个3,但是要保留一个时,当两个指针一样时,删掉一个,然后前面的指针继续指向下一个,一直这样,两个指针相同时,删掉一个,直到链表结束)
注意:如果链表只有一个节点或者没有节点的时候,要单独处理,这里有一个原则,就是一般情况下,如果你写的代码能正常处理一个节点都没有的情况就不用判断,如果不行,就要判断;还有一个就是,如果你一开始就要动两个或两个指针以上的指针,就要单独处理一下,剩下的不用处理
具体实现代码如下:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if(pHead==NULL||pHead->next==NULL)
return pHead;
struct ListNode* prev=NULL;
struct ListNode* n1=pHead;
struct ListNode* n2=n1->next;
while(n2!=NULL)
{
if(n1->val!=n2->val)
{
prev=n1;
n1=n2;
n2=n2->next;
}
else
{
while(n2&&n1->val==n2->val)
{
n2=n2->next;
}
if(prev!=NULL)
{
prev->next=n2;
}
else
{
pHead=n2;
}
//删除掉重复的节点
while(n1!=n2)
{
struct ListNode* next=n1->next;
free(n1);
n1=next;
}
n1=n2;
if(n2)
n2=n2->next;
}
}
return pHead;
}
};