1.题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
2.问题分析
方法一:
因为重复的节点不保留,可以使用map来统计节点出现的次数,如果出现的次数大于1,那么就不添加到新的链表中,反之,只出现一次的链表就添加到新链表中
方法二:
虽然方法一思路上简单点,但是没有充分利用链表是排序这个已知条件。
因为链表是排序的,如果一个节点是重复节点,那么它后面就会有至少一个节点和这个节点值相等,这些节点我们都不保留。之后我们从与这个节点值不一样的节点开始,继续进行上面判断,直到节点到链表尾部。
具体分析可以见源代码。
3.源代码
方法一:
ListNode* deleteDuplication(ListNode* pHead)
{
if(pHead == NULL)
return NULL;
map<int,int> times;
ListNode* pNode = pHead;
//统计出现次数
while(pNode != NULL)
{
++times[pNode->val];
pNode = pNode->next;
}
//使用一个空的头结点,因为新链表的头节点可能不是原链表的头结点
//避免了查找新链表的头结点
ListNode emptyHead(0);
ListNode* pNewNode = &emptyHead;
pNode = pHead;
while(pNode != NULL)
{
//添加到新链表中
if(times[pNode->val] == 1)
{
pNewNode->next = pNode;
pNewNode = pNewNode->next;
pNode = pNode->next;
}
//删除该节点
else
{
ListNode* pNext = pNode->next;
delete pNode;
pNode = pNext;
}
}
//最后一个节点的next指针置空
pNewNode->next = NULL;
return emptyHead.next;
}
方法二:
ListNode* deleteDuplication(ListNode* pHead)
{
if(pHead == NULL)
return NULL;
//使用一个空的头结点,因为新链表的头节点可能不是原链表的头结点
//避免了查找新链表的头结点
ListNode emptyHead(0);
ListNode* pNewNode = &emptyHead;
ListNode* pNode = pHead;
while(pNode != NULL)
{
ListNode* pNext = pNode->next;
//判断下一个节点是否与当前节点的值相等
//如果相等,那么就过滤掉并且删除掉与pNode->val值相等的节点
//使pNode指向新的节点
if(pNext != NULL && pNext->val == pNode->val)
{
int value = pNode->val;
delete pNode;
while(pNext != NULL && pNext->val == value)
{
ListNode* temp = pNext->next;
delete pNext;
pNext = temp;
}
//使pNode指向新的节点
pNode = pNext;
}
else
{
//非重复的节点,添加到新的链表中
pNewNode->next = pNode;
pNewNode = pNewNode->next;
pNode = pNext;
}
}
//最后一个节点的next指针置空
pNewNode->next = NULL;
return emptyHead.next;
}