删除链表中重复的结点
- 参与人数:611时间限制:1秒空间限制:32768K
- 通过比例:17.54%
- 最佳记录:0 ms|8552K(来自 算法导论)
题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
题目通俗易懂(ps:我理解错了,编程删去多余重复结点了。。。哎,语文老师不要打我。)
先讲讲我的思路吧:要是这些题放以前我打死也不会用链表做的,毕竟数组这么方便是吧。
链表解法:考虑情况1、空链表
2、只有一个数的链表
3、多个数组成的链表
其中一、二情况特判;对于三的情况再分情况讨论;eg:1 1 2 2
2 2 2 2 2 2
3 4 5 6 7
我的想法是用一个头结点来指向该链表中不重复出现的数字,用bool 来标记出现多次的数;另指针p指向链表
头,q是p的下一个结点q=p->next,然后循环往后找重复的就标记bool为false,当遇到不
重复的就判断bool,bool为真就加入,为假就往后继续。最后一个再特判一下bool就可以了。
注
意返回的是头指针的next;
关键步骤请在草稿纸上模拟一下,加深印象。
//链表有序
#include<stdio.h>
#include<iostream>
#include <stdlib.h>
using namespace std;
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if(!pHead) return NULL;
if(!pHead->next) return pHead;
ListNode *p,*q,*r,*head;
head=new ListNode(NULL);
r=head;
p=pHead;
bool bo=true;
if(p->next)
{
q=p->next;
while(q)
{
if(q->val==p->val){bo=false;p=q;q=q->next;}
else
{
if(bo){r->next=p;r=p;}
p=q;
q=q->next;
bo=true;
}
}
if(bo){r->next=p;r=p;}
r->next=NULL;
}
return head->next;
}
ListNode* CreatList(ListNode *pHead,int n)
{
if(n==0) return NULL;
ListNode *p,*q;
pHead=new ListNode(NULL);
p=pHead;
cin>>p->val;
int x;
while(--n)
{
cin>>x;
q=new ListNode(x);
p->next=q;
p=q;
}
return pHead;
}
};
int main()
{
int n,m;
Solution so;
ListNode *L;
cin>>n;
L=so.CreatList(L,n);
ListNode *ans=so.deleteDuplication(L);
while(ans)
{
printf("%d\t",ans->val);
ans=ans->next;
}
return 0;
}