【資料結構】連結串列相關練習題:刪除連結串列中重複的節點
阿新 • • 發佈:2018-12-16
-
題目描述
在一個排序的連結串列中,存在重複的結點,請刪除該連結串列中重複的結點,重複的結點不保留,返回連結串列頭指標。 例如,連結串列1->2->3->3->4->4->5 處理後為 1->2->5。
-
思路分析
我們可以給定兩個一前一後的指標n1,n2,當兩個指標的val不一樣時,不需要處理,直到一樣時,n1不動,讓第二個指標n2往後走,走到跟n2不相同的地方,把n1和n2之間的數字刪掉,再想辦法把n1和n2連結起來,只要遇到相同的,就又重複前面的邏輯,這裡還有一個問題要注意,就是刪除時,得有它的前一個指標,所以還得有一個指標永遠記錄n1的前一個。
(補充一個簡單的連結串列的去重:如果是有n個3,但是要保留一個時,當兩個指標一樣時,刪掉一個,然後前面的指標繼續指向下一個,一直這樣,兩個指標相同時,刪掉一個,直到連結串列結束)
注意:如果連結串列只有一個節點或者沒有節點的時候,要單獨處理,這裡有一個原則,就是一般情況下,如果你寫的程式碼能正常處理一個節點都沒有的情況就不用判斷,如果不行,就要判斷;還有一個就是,如果你一開始就要動兩個或兩個指標以上的指標,就要單獨處理一下,剩下的不用處理
具體實現程式碼如下:
/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } }; */ class Solution { public: ListNode* deleteDuplication(ListNode* pHead) { if(pHead==NULL||pHead->next==NULL) return pHead; struct ListNode* prev=NULL; struct ListNode* n1=pHead; struct ListNode* n2=n1->next; while(n2!=NULL) { if(n1->val!=n2->val) { prev=n1; n1=n2; n2=n2->next; } else { while(n2&&n1->val==n2->val) { n2=n2->next; } if(prev!=NULL) { prev->next=n2; } else { pHead=n2; } //刪除掉重複的節點 while(n1!=n2) { struct ListNode* next=n1->next; free(n1); n1=next; } n1=n2; if(n2) n2=n2->next; } } return pHead; } };