劍指offer之刪除連結串列中重複的結點
阿新 • • 發佈:2018-10-31
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;
}