[編程|20分] 刪除鏈表中重複的結點
時間限制:C/C++ 1秒,其他語言 2秒
空間限制:C/C++ 32768K,其他語言 65536K
題目描述
在一個排序的鏈表中,存在重複的結點,請刪除該鏈表中重複的結點,重複的結點不保留,返回鏈表頭指針。 例如,鏈表1->2->3->3->4->4->5 處理後爲 1->2->5
思路:
1.先給原鏈表添加一個頭結點方便處理
2.使用3個指針,p一個指向前一個節點(從創建的創建的新節點開始),q指向當前節點,p->next一個指向下一個節點
3.噹噹前節點跟後一個節點相等時,不斷往後遍歷,找到第一個不等於當前節點的節點;然後用p 指向它,將q後移一位
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead){
ListNode* head=new ListNode(0);
ListNode* p=head;
ListNode* q=pHead;
while(q){
while(q!=NULL&&q->next!=NULL&&q->next->val==q->val){
int tmp=q->val;
while(q!=NULL&&q->val==tmp)
q=q->next;
}
p->next=q;
p=p->next;
if(q)
q=q->next;
}
return head->next;
}
};
解法2.遞歸實現
化繁爲簡,先找到第一個符合的結點,以後在該處遞歸執行邏輯直到鏈表結束。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* deleteDuplication(ListNode* phead){
if (phead==NULL) return NULL;//鏈表爲空返回NULL
if (phead!=NULL && phead->next==NULL) return phead;// 鏈表無節點或只有一個節點也無需繼續,直接返回NULL
ListNode* curr = NULL;
if (phead->val == phead->next->val){// 當前結點是重複結點
curr=phead->next->next;//此時cur指向第三個節點
while (curr != NULL && phead->val==curr->val)
// 跳過值與當前結點相同的全部結點,找到第一個與當前結點不同的結點
curr=curr->next;
return deleteDuplication(curr); // 從第一個與當前結點不同的結點開始遞歸
}
else {// 當前結點不是重複結點
curr=phead->next;// 保留當前結點,從下一個結點開始遞歸
phead->next=deleteDuplication(curr);
return phead;
}
}
};
python暴力解法
把所有節點的值放到一個列表中,再篩選出值數量爲1的值。
再新建一個鏈表返回即可。
class Solution:
def deleteDuplication(self, pHead):
res = []
while pHead:
res.append(pHead.val)
pHead = pHead.next
res = list(filter(lambda c: res.count(c) == 1, res))
dummy = ListNode(0)
pre = dummy
for i in res:
node = ListNode(i)
pre.next = node
pre = pre.next
return dummy.next