题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
这个题目到最后自己也没能调试出来,虽然在自己最初的代码上有了很多的改动但是还是不能正确的完全通过测试。
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if (pHead == NULL)
return NULL;
if (pHead->next == NULL)
return pHead;
if (pHead->next->next == NULL)
{
if (pHead->val == pHead->next->val)
{
pHead->next = NULL;
}
return pHead;
}
ListNode *preNow = pHead;
ListNode *phead = pHead;
ListNode *now = pHead;
ListNode *preFind = NULL;
ListNode *Find = NULL;
while (now)
{
preFind = now;
Find = preFind->next;
while (Find)
{
if (now->val == Find->val)
{
preFind->next = Find->next;
Find = Find->next;
preNow->next = now->next;
break;
}
else
{
preFind = Find;
Find = Find->next;
}
}
if (now == pHead)
{
preNow = now;
}
now = now->next;
}
return phead;
}
};
这是我最终没能通过的代码,我是这样想的我想通过四个指针来实现对比重复的结点并且删除重复的结点,
这是我最初的想法,但是发现怎么测试都不成功之后发现了问题,题目所给的链表中重复的结点都是临近的,而不是我想象的那样可能链表头一个链表尾一个。虽然说看起来问题好像简单了一点,但是即使是这样还是有很多种情况的。最难以处理的一种情况就是我们现在要删除的链表里边包含我们的头结点,最初我设想的是我现在开始找两个相同的结点,找到之后我来判断一下我前边的那个节点是不是等于我们的pHead如果是的话,我们返回的结点直接返回我们Find 的next就可以了,这种确实可以来实现,但是这种情况很复杂并且不能和其他情况一概而论,也就是不能写到同一个循环里,之后我在别人提交的代码里发现了一个好处理的代码。
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if (pHead == NULL)
return NULL;
if (pHead->next == NULL)
return pHead;//没有结点或者说只有一个结点的时候直接返回
ListNode *ret = pHead;
ListNode *Now = pHead;
ListNode *Find = pHead->next;
ListNode *newhead = new ListNode(-1);
ListNode *preNow = newhead;
newhead->next = pHead;
while (Now!=NULL&&Now->next!=NULL)
{
Find = Now->next;
if (Now->val == Find->val)
{
while (Find->val == Now->val&&Find!=NULL)
{
Find = Find->next;
}
preNow->next = Find;
Now = Find;
}
else
{
preNow = Now;
Now = Now->next;
}
}
return newhead->next;
}
};
因为我们删除的时候一定是要有你删除的这个结点的前一个节点的,但是由于这个题里边的重复结点都是连续的,所以这里只需要三个节点,一个是前边结点的prev一个是前边结点一个是后边结点,这样的话如果要是删除这一串结点我们只是让前结点的prev的next指向我们的后边结点的next就可以了。
为了统一处理我们这里创建了一个新的结点新结点的next是我们原指针的头结点,也就是说我们在头指针上加了一个prev这样让我们的头指针和其他结点没有什么区别这样的话,能够让链表中的指针统一的去处理。
如果发现指针相同的时候里边我们用到了while循环就是为了删除1->1->1->1->1->1->5这种链表的。我们返回的时候直接返回我们新建结点的next就可以了,因为如果删除了头结点我们的prev也相应的变化了,但是如果没有删除那我们新建结点的next就是我们最初原链表的头指针。