题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
下面的程序中Solution通过了牛客网的测试,系统创建的链表中没有带头结点,而是在Solution中自己建了一个头结点
#include<iostream>
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==NULL||pHead->next==NULL) //链表第一个或第二个节点为空则直接退出
return pHead;
ListNode* head=new ListNode(-1); //添加一个头结点
head->next=pHead;
ListNode* pre=head;
ListNode* pnode=pHead;
while(pnode&&pnode->next)
{
while(pnode->next&&(pnode->next->val==pnode->val))
pnode=pnode->next;
if(pre->next!=pnode)
{
pre->next=pnode->next; //让pre的next域指向当前节点的next,但是不移动pre指针,也许下一个结点仍是重复结点
}
else
{
pre=pnode; //将pre指针移动到当前节点,且pre的next指针域已经改变,删除了pre和pnode之间的结点
} //等价于pre->next=pnode;pre=pre->next;其实在pre->next=pnode->next已经确定了pre的next域
pnode=pnode->next;
}
return head->next; //去掉自己添加的头结点
}
};
ListNode* Creat_ListNode()
{
ListNode *L,*s,*rear=NULL;
L=(ListNode *)malloc(sizeof(ListNode));
L->next=NULL;
rear=L;
int x;
while(cin>>x) //创建带头结点链表的尾插法
{
s=(ListNode *)malloc(sizeof(ListNode));
s->val=x;
rear->next=s;
rear=s;
}
rear->next=NULL;
return L->next; //返回时去掉头结点
}
void print(ListNode* pHead)
{
ListNode* p=pHead;
while(p)
{
cout<<p->val<<" ";
p=p->next;
}
cout<<endl;
}
void main() //测试程序
{
ListNode* L;
L=Creat_ListNode();
Solution text1;
L=text1.deleteDuplication(L);
print(L);
}
下面是自己创建了带头结点的链表,在Solution中不用自己再添加头结点,并且在本地上通过了测试算例:
#include<iostream>
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->next==NULL||pHead->next->next==NULL) //链表第一个或第二个节点为空则直接退出
return pHead;
// ListNode* head=new ListNode(-1); //添加一个头结点
// head->next=pHead;
ListNode* pre=pHead;
ListNode* pnode=pHead->next;
while(pnode&&pnode->next)
{
while(pnode->next&&(pnode->next->val==pnode->val))
pnode=pnode->next;
if(pre->next!=pnode)
{
pre->next=pnode->next; //让pre的next域指向当前节点的next,但是不移动pre指针,也许下一个结点仍是重复结点
}
else
{
pre=pnode; //将pre指针移动到当前节点,且pre的next指针域已经改变,删除了pre和pnode之间的结点
} //等价于pre->next=pnode;pre=pre->next;其实在pre->next=pnode->next已经确定了pre的next域
pnode=pnode->next;
}
return pHead; //去掉自己添加的头结点
}
};
ListNode* Creat_ListNode()
{
ListNode *L,*s,*rear=NULL;
L=(ListNode *)malloc(sizeof(ListNode));
L->next=NULL;
rear=L;
int x;
while(cin>>x) //创建带头结点链表的尾插法
{
s=(ListNode *)malloc(sizeof(ListNode));
s->val=x;
rear->next=s;
rear=s;
}
rear->next=NULL;
return L; //返回时去掉头结点
}
void print(ListNode* pHead)
{
ListNode* p=pHead->next;
while(p)
{
cout<<p->val<<" ";
p=p->next;
}
cout<<endl;
}
void main() //测试程序
{
ListNode* L;
L=Creat_ListNode();
Solution text1;
L=text1.deleteDuplication(L);
print(L);
}