题目描述
删除链表中的重复结点
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。
示例1:
输入:{1,2,3,3,4,4,5}
输出:{1,2,5}
题解
本题可采用三个指针,指针prev用来包存前一个结点的信息,指针tail 和 tmp 用来寻找重复结点。(因为链表是已经排好序的,所有重复结点一定排在一起)
初始情况
①当tail -> val 和 tmp -> val 不相同时,更新这三个指针的位置,则prev = tmp 、tmp = tail 、tail = tail -> next。
②当tmp 和 tail 的 val 相同时,tail 就一直向后走,直至和 tmp 的 val 不同
然后tmp一直向后走循环的删除这些重复结点,直至tmp == tail 为止
③循环步骤①②,直至tail指向NULL为止
题解代码
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if(pHead == NULL || pHead->next == NULL)
{
return pHead;
}
ListNode* prev = NULL,*tail = pHead->next,*tmp = pHead;
while(tail)
{ //当结点不相同时,则更新三个指针的位置
if(tmp->val != tail->val)
{
prev = tmp;
tmp = tail;
tail = tail->next;
}
else{
//获得不相同的结点
while(tail && tmp->val == tail->val)
{
tail = tail->next;
}
//删除从tmp到tail之间的值
while(tmp!=tail)
{
ListNode* del = tmp;
tmp = tmp->next;
free(del);
}
if(prev == NULL)
{ //如果开始就有两个结点是相等的,则直接将首指针给tmp/tail,因为第3个while循环已经得出tmp == tail了
pHead = tmp;
}else{
//不是的话就用prev进行连接
prev->next = tmp;
}
}
//若为空,则表明链表的结点从某个位置一直到尾部是相等的,则tmp不变即可(此时tail也为空)
//若不为空,则更新tail的指针,往后走一个。
if(tmp)
{
tail = tmp->next;
}
}
return pHead;
}
};