[编程|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