剑指offer之删除链表中重复的结点

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;
}

猜你喜欢

转载自blog.csdn.net/zqw_yaomin/article/details/83180758