鏈表------刪除有序單鏈表中重復的節點


在一個排序的鏈表中,存在重復的結點,請刪除該鏈表中重復的結點,重復的結點不保留,返回鏈表頭指針。 例如,鏈表1->2->3->3->4->4->5 處理后為 1->2->5

第一種方法:遞歸 //耗時5ms

ListNode* deleteDuplication(ListNode* pHead)
{
    if (pHead == nullptr || pHead->next == nullptr) { // 只有0個或1個結點,則返回
        return pHead;
    }
    if (pHead->val == pHead->next->val) { // 當前結點是重復結點
        ListNode *pNode = pHead->next;
        while (pNode != nullptr && pNode->val == pHead->val) {
            // 跳過值與當前結點相同的全部結點,找到第一個與當前結點不同的結點
            pNode = pNode->next;
        }
        return deleteDuplication(pNode); // 從第一個與當前結點不同的結點開始遞歸
    }
    else { // 當前結點不是重復結點
        pHead->next = deleteDuplication(pHead->next); // 保留當前結點,從下一個結點開始遞歸
        return pHead;
    }
}

第二種方法:每次找一個不重復的元素,加入鏈表//耗時7ms

ListNode* deleteDuplication(ListNode* pHead)
{

// 解法2:每次找一個不重復的元素,加入鏈表
if (pHead == nullptr)
return pHead;
ListNode *newhead = new ListNode(1);
ListNode *index = newhead;
ListNode *p = pHead;
bool rept = false;

while (p != nullptr){
rept = false;
while (p->next != nullptr && p->val == p->next->val){
rept = true;
p = p->next;
}
if (rept == false){
index->next = new ListNode(p->val);
index = index->next;
p = p->next;
}
else{
if (p->next == nullptr){
break;
}
else{
p = p->next;
}
}
}

return newhead->next;
}

第三種方法:耗時3ms

ListNode* deleteDuplication(ListNode* pHead)
    {
        if(pHead==nullptr || pHead->next==nullptr) return pHead;
        ListNode *pre=NULL;
        ListNode *p=pHead;
        ListNode *q=p->next;
        
        while(p!=nullptr)
        {
//當前結點p,(其實是p指向當前結點),與它下一個結點p->next的val相同,說明要刪掉有這個val的所有結點
            if(p->next!=NULL && p->next->val==p->val)
            {
                q=p->next;
          //找到q,它指向最后一個與p val相同的結點,那p 到 q (包含) 都是要刪除的
                while(q!=nullptr && q->next!=nullptr && q->next->val==q->val)
                    q=q->next;
          //如果p指向鏈表中第一個元素,p -> ... -> q ->... , 要刪除p到q, 將指向鏈表第一個元素的指針pHead指向q->next。
                if(p==pHead) pHead=q->next;
                else pre->next=q->next;  //如果p不指向鏈表中第一個元素,pre -> p ->...->q ->... ,要刪除p到q,即pre->next = q->next
          //當前處理的p要向鏈表尾部移動
                p=q->next;
            }
            else
            {
                pre=p;
                p=p->next;
            }
        }
        return pHead;
    }

 

第四種方法:java 使用HashMap記錄每個節點是否重復出現,時間復雜度為O(N),空間復雜度為O(N)

public ListNode deleteDuplication(ListNode pHead)
    {
        // 解法1:使用hashMap記錄個數
        if(pHead==null)
            return pHead;
        HashMap<Integer, Boolean> map = new HashMap<Integer, Boolean>();
        ListNode cur = pHead;
        while(cur != null){
            if(map.containsKey(cur.val) == false){
                map.put(cur.val, true);
            }else{
                map.put(cur.val, false);
            }
            cur = cur.next;
        }
         
        Set<Integer> set = map.keySet();
        boolean isfst = true;
        ListNode pre = pHead;
        for (int temp : set){
            if (map.get(temp) == true){
                if(isfst){
                    pHead.val = temp;
                    isfst = false;
                }
                else{
                    pre.next.val = temp;
                    pre = pre.next;
                }
            }
         
        }
        if(isfst) // 鏈表中只含有重復節點
            return null;
        else     // 鏈表含有不重復的節點
            pre.next = null;
        return pHead;
    }
}
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM