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

劍指offer-刪除連結串列中重複的結點

描述

在一個排序的連結串列中,存在重複的結點,請刪除該連結串列中重複的結點,重複的結點不保留,返回連結串列頭指標。 例如,連結串列1->2->3->3->4->4->5 處理後為 1->2->5 求解思路
  1. 遍歷兩個相鄰的節點,如果相等,就繼續向後刪除值相同的節點。
  2. 刪除重複節點前,需要一個節點來記錄重複節點前的字首節點。
  3. 由於在刪除重複節點時,字首節點可能並不存在,這時候需要分兩種情況分析,比較繞。
 1 /*
 2 struct ListNode {
 3     int val;
 4     struct ListNode *next;
5 ListNode(int x) : 6 val(x), next(NULL) { 7 } 8 }; 9 */ 10 class Solution { 11 public: 12 ListNode* deleteDuplication(ListNode* pHead) { 13 // 又沒仔細看題,是重複出現的節點都要刪除 14 if(pHead==nullptr || pHead->next==nullptr){ 15 return pHead; 16 } 17 ListNode* fp=pHead,*rp=pHead; //
刪除流程的前後節點 18 ListNode* nH=nullptr,*nR=nullptr; // 不好記錄重複節點的前節點,用新的連結串列 19 bool hNode=true; 20 // 如果一個節點的next等於next的next,開始清除 21 while(rp!=nullptr && rp->next!=nullptr){ 22 if(rp->next->val==rp->val){ // 如果fp後面的兩個節點相同,就準備刪除了 23 int
nv=rp->val; 24 while(rp!=nullptr && rp->val==nv){ 25 ListNode* tp=rp; 26 rp=rp->next; 27 delete tp; 28 } 29 if(hNode){ 30 fp=rp;pHead=rp; 31 }else{ 32 fp->next=rp; 33 } 34 }else{ 35 if(hNode){ // 當有字首節點時,需要記錄字首節點,fp不能++ 36 pHead=rp;rp=rp->next; 37 hNode=false; 38 }else{ 39 fp=fp->next;rp=rp->next; 40 } 41 } 42 } 43 return pHead; 44 } 45 };

  改進:在原始連結串列前加一個節點(-1)。

 1 class Solution {
 2 public:
 3     ListNode* deleteDuplication(ListNode* pHead)
 4     {
 5         ListNode *vhead = new ListNode(-1);
 6         vhead->next = pHead;
 7         ListNode *pre = vhead, *cur = pHead;       
 8         while (cur) {
 9             if (cur->next && cur->val == cur->next->val) {
10                 cur = cur->next;
11                 while (cur->next && cur->val == cur->next->val) {
12                     cur = cur->next;
13                 }
14                 cur = cur->next;
15                 pre->next = cur;
16             }
17             else {
18                 pre = cur;
19                 cur = cur->next;
20             }
21         }
22         return vhead->next;
23     }
24 };
心之所願,永不相忘