1. 程式人生 > >劍指offer之刪除連結串列中重複的結點

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