我今天真的是心態崩了,我的天,自己寫了一遍沒有通過,又按照書上的又敲了一遍還是提示通過率爲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;//每次返回的都是頭
}
}
};