劍指offer[18-2] 刪除了鏈表中重複的節點(不保留)

我今天真的是心態崩了,我的天,自己寫了一遍沒有通過,又按照書上的又敲了一遍還是提示通過率爲0,我太難了

今天就來細細的分析這個!

上題目:

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

題目解析:

主要考察刪除鏈表中的節點,特殊的地方就在於刪除重複出現過的節點(一個也不保留),同時鏈表又是排序後的,因此重複的節點肯定是挨着的(記住這句話,不然很尷尬)。

思路:使用兩個指針,1)一個用來遍歷整個鏈表 (額,我好像有點廢話了,,,

                                    2)用來將不重複的節點串起來

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* deleteDuplication(ListNode* pHead)
    {
        if(pHead==nullptr || pHead->next==nullptr) return pHead;
        ListNode* pPre = nullptr; // 用於鏈接不重複的節點
		ListNode* result = nullptr;// 鏈接不重複的節點的頭指針  
        ListNode* pCurrent = pHead; // 用於遍歷整個鏈表
        bool isFirst = true;
        while(pCurrent!=nullptr) { 
            bool isDelete = false;  // 判斷節點是否需要刪除
            ListNode* pNext = pCurrent->next;  // 當前節點的下一個節點
            if(pCurrent->next!=nullptr && pCurrent->val == pNext->val) // 刪除條件-》重複
                isDelete = true;
            if(!isDelete) {
                if(isFirst) {  // 因爲開始的時候初始化爲nullptr所以需要設置一下
                    pPre = pCurrent;
                    result = pPre; // 用於鏈接不重複的節點的頭指針 這裏就是我犯傻的地方,我居然沒留一個頭指針,直接將pPre返回了。。。
			        isFirst = false;   //表明頭指針不爲空
                } else {
                    pPre->next = pCurrent; // 不是第一個節點
                    pPre = pPre->next;
                }
            } else {
                int val = pCurrent->val;  //回去待刪除的節點的值,因爲重複可能爲多次
                ListNode *pDelete = pCurrent;  //用於刪除重複值
                while(pDelete!=nullptr && pDelete->val == val) {
                    pNext = pDelete ->next;
                    delete pDelete;
                    pDelete = nullptr;
                    pDelete = pNext;
                }
                
            }
              pCurrent = pNext; // 更新原始鏈表中的pCurrent
        }
        if(pPre!=nullptr) pPre->next=nullptr;  //對尾部進行處理
        return result;  //返回頭指針
       
    }
};

 下面還有大佬寫的遞歸格式的,怎一個牛逼了得!:

鏈接:https://www.nowcoder.com/questionTerminal/fc533c45b73a41b0b44ccba763f866ef?answerType=1&f=discussion
來源:牛客網

//遞歸求解 C++ 有問請指出謝謝,
//理解遞歸了寫起來代碼蠻簡單,研讀別人代碼這個過程異常艱難耗時,所以我把思路都寫出來了方便理解;
//每次遞歸:刪除當前指針向後的連續節點。保證下一次遞歸的頭結點與之後的不重複;找到下一個不重複的節點與其相連
class Solution {
public:
    ListNode* deleteDuplication(ListNode* pHead)
    {
        if (!pHead || !pHead->next) return pHead;//0/1個結點直接返回頭,也是遞歸出口,NULL的話結束
        ListNode* cur;
        if ( pHead->next->val==pHead->val){//當前結點等於下一個
            cur=pHead->next;//cur指向下一個
            while (cur->next && cur->next->val==pHead->val)//有下一個且還想等
                cur=cur->next;//走到相等的最後一個,此節點和前面的還是相等的
            return deleteDuplication(cur->next);//遞歸往後第一個不相等的,NULL的話結束             
        }
        else {//此節點和下個不相等
            cur=pHead->next;//下個結點遞歸過去
            pHead->next=deleteDuplication(cur);//重構鏈表
            return pHead;//每次返回的都是頭
        }    
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章